Sommaire

BONJOUR
Musique "Invention BWV784" J.S. BACH 1685-1750

Tutoriel et Help

Style & CSS


Accueil

Accueil CHM

Normal, dit comme ça,
vous ne risquez pas de comprendre.


Sommaire - HTML et Programmation de Toutes Sortes

Vu dans ... http://www.electronique-et-informatique.fr/Electronique-et-Informatique/HTML_et_Programmes/Sommaire_HTML_Programmes.php

Sommaire - HTML et Programmation de Toutes Sortes :

Sommaire - HTML et Programmation ; A noter : vous pouvez utiliser un bloc note pour faire tous vos essais

1. - Caractères en Gras avec leurs Balises HTML et l'Accentuation
2. - Structuration du Document avec le Minimum Langage HTML ainsi que la Méthode de travail
3. - Les Divisions HTML avec leurs différents attributs
4. - Listes Descriptives, Listes Régulières, Listes Ordonnées et non Ordonnées et Listes Imbriquées
5. - Les Styles Physiques, les Styles Logiques et les Styles Paragraphes
6. - Les Liens Hypertextuels, Ancres, onMouseOver, onMouseOut et onClick avec des Exemples
7. - Inclusions d'Imagerie et Alignement des Images, Exemples de Modification d'Images
8. - Les Mises en Page des Paragraphes, Mises en Page des Colonnes avec Imagerie
9. - Les Feuilles de Style, Classes de Style, SPAN avec l'Attribut CLASS et Définitions des Fichiers Externes
10. - Positionnement Dynamique, Les Couches, Dynamisme des Couches, Méthodes des Couches et Évenements
11. - Les Images Cliquables, Méthode Ismap, Méthode Usemap et les Événements liés d'une Carte Cliquable Animée
12. - Les Tableaux et Exemple de Tableau Intégrant Divers Éléments
13. - Création des Frames, FRAMESET, FRAME, Utilisation des Frames et les Frames avec JavaScript
14. - Les Méta-Informations et leurs Utilisations de Client-pull - REFRESH
15. - La Programmation et les Limites d'emploi HTML avec trois Rubriques, Mode Déplié et Replié
16. - Les Formulaires, Description des Balises de Formulaire et des Événements JavaScript Associés
16. 1. - Balises Input, Attributs, Name, Size, Value, Text, Objet Text, Password, Submit, Checkbox, Checked et Radio
16. 2. - Balises Select, Option, Textarea, Type Hidden et Récapitulation des Options Select avec exemples

Vu dans ... http://www.electronique-et-informatique.fr/Electronique-et-Informatique/HTML_et_Programmes/Sommaire_HTML_Programmes.php


Les Balises et les Accentuations

Les Balises et l'Accentuation :

Les balises :

Nous avons défini le langage HTML (HyperText Markup Language) comme un langage permettant de décrire la structure d'un document Web. Pour ce faire, il faut encadrer chacune des différentes structures du texte par une paire de Balises, une au début (<>) et une autre à la fin </>.

Ces Balises seront bien sûr invisibles au moment de l'affichage du document du site Web.

Dans un Traitement de texte, lorsque l'on veut mettre un mot en gras, on sélectionne les caractères, puis on clique généralement sur une petite icône qui a pour effet de les faire passer dans la graisse choisie. De façon interne et sans que cela apparaisse à l'écran, le traitement de texte inscrit dans le fichier un code indiquant qu'une zone en caractères gras commence, puis viennent ensuite les caractères en question ; enfin, un nouveau code indique le retour aux caractères standard.

Ce sont ces codes que l'on appelle des balises. Dans le langage HTML, la gestion des balises est à la charge de l'auteur.

Les balises sont déimitées par les signes < (inférieur à) et > (supérieur à).

EXEMPLE :

Monsieur Pierre part en vacances <balise> et il reviendra dans une semaine </balise> pour reprendre son travail.

Remarquez le caractère / en couleur bleue, dans la balise de fin.

Voici un exemple de saisie pour passer un groupe de caractères en gras dans le langage HTML (utilisation de la balise <B> pour Bold ou gras) :

Reprenons notre exemple ci-dessus :

Monsieur Pierre part en vacances <b> et il reviendra dans une semaine </b> pour reprendre son travail.

Voici un aperçu, en cliquant ici. (Exemple 1)

Nous allons faire volontairement une faute de syntaxe, en oubliant de mettre, par exemple, la balise de fin comme ci-après : </b>

Reprenons notre exemple : Monsieur Pierre part en vacances <b> et il reviendra dans une semaine pour reprendre son travail.

Nous voyons bien, en oubliant la balise de fin de caractères gras (</b>) concernant notre exemple, ce qui donne ceci :

Monsieur Pierre part en vacances et il reviendra dans une semaine pour reprendre son travail.

Ou encore pour aller se promener.

Vous pouvez voir l'aperçu dans votre Navigateur ou Browser, en cliquant ici. (Exemple 2)

Nous savons dorénavant que le paragraphe ci-dessus est en caractères graisse choisie et que, nous voyons bien également que certains mots sont largement en gras, or que, on voulait mettre uniquement la phrase en graisse choisie : "et il reviendra dans une semaine pour reprendre son travail." Tout simplement, nous avions oublié de mettre la balise de fin </b>.

C'est pourquoi qu'il ne faille pas oublier certaines balises de fin (</>).

Si l'on veut utiliser les deux caractères <> dans le texte courant, il faudra trouver un artifice afin que le Browser ou Navigateur ne tente pas de les interpréter comme balises. On les remplacera par leurs entités HTML équivalentes :

  • Le caractère > sera remplacé par gt;, n'oublions pas de mettre un & commercial devant la lettre g et à la fin de la lettre t, le point virgule.

  • Le caractère < sera remplacé par lt;, n'oublions pas de mettre un & commercial devant la lettre l et à la fin de la lettre t, le point virgule.

    • Ceci produira dans la fenêtre du browser :

    Les signes < et > délimitent les balises HTML. Pour regarder l'aperçu, cliquez ici (Exemple 3)

    A noter : Le texte à l'intérieur des balises peut être indifférent, en majuscule ou en minuscule :

    <b> ou <B> sont strictement équivalents.

    N.B. : Pour que vous puissiez voir le code HTML dans votre navigateur pour visualiser, il suffira de cliquer avec le bouton droit de votre souris, afin d'ouvrir le menu contextuel, puis de pointer sur "Afficher le code source de la page".

    L'accentuation :

    L'enregistrement des fichiers contenant les documents HTML est effectué sur la machine serveur en code ASCII 7 bits, ce qui ne permet pas d'accentuer directement le texte. On utilisera donc des mots-clés pour tous les caractères accentués et autres symboles, de façon identique au traitement des caractères < > décrits au paragraphe ci-dessus.

    (Le Code ASCII 7 bits définit sur les 7 bits de poids le plus faible d'un octet un jeu de 128 caractères incluant les chiffres, les minuscules, les majuscules, un certain nombre de signes ainsi que des caractères de contrôle non imprimables. Le huitième bit sert au contrôle de parité pour valider l'exactitude de la transmission. Il ne reste pas assez de place dans ce code pour représenter les caractères accentués).

    C'est pourquoi que nous allons vous présenter certains Caractères accentués, symboles, afin d'obtenir certains codes des mots-clés pour l'alphabet ISO Latin 1 que nous expliquerons cela ultérieurement dans un paragraphe ou dans une leçon consacrée à cet effet.

    Caractères accentués, Symboles
Caractère | Syntaxe | Syntaxe (ASCII) | Description
Á | &Aacute; | &#193; | A capitale, accent aigu
À | &Agrave; | &#192; | A capitale, accent grave
Â | &Acirc; | &#194; | A capitale, accent circonflexe
Ã | &Atilde; | &#195; | A capitale, tilde
Å | &Aring; | &#197; | A capitale
Ä | &Auml; | &#196; | A capitale, tréma
Æ | &AElig; | &#198; | Æ capitale
Ç | &Ccedil; | &#199; | C capitale, cédille
É | &Eacute; | &#201; | E capitale, accent aigu
È | &Egrave; | &#200; | E capitale, accent grave
Ê | &Ecirc; | &#202; | E capitale, accent circonflexe
Ë | &Euml; | &#203; | E capitale, tréma
Í | &Iacute; | &#205; | I capitale, accent aigu
Ì | &Igrave; | &#204; | I capitale, accent grave
Î | &Icirc; | &#206; | I capitale, accent circonflexe
Ï | &Iuml; | &#207; | I capitale, tréma
Ñ | &Ntilde; | &#209; | N capitale, tilde
Ó | &Oacute; | &#211; | O capitale, accent aigu
Ò | &Ograve; | &#210; | O capitale, accent grave
Ô | &Ocirc; | &#212; | O capitale, accent circonflexe
Õ | &Otilde; | &#213; | O capitale, tilde
Ö | &Ouml; | &#214; | O capitale, tréma
Ø | &Oslash; | &#216; | O capitale, barré
Ú | &Uacute; | &#218; | U capitale, accent aigu
Ù | &Ugrave; | &#217; | U capitale, accent grave
Û | &Ucirc; | &#219; | U capitale, accent circonflexe
Ü | &Uuml; | &#220; | U capitale, tréma
Ý | &Yacute; | &#218; | Y capitale, accent aigu
á | &aacute; | &#225; | a minuscule, accent aigu
à | &agrave; | &#224; | a minuscule, accent grave
â | &acirc; | &#226; | a minuscule, accent circonflexe
ã | &atilde; | &#227; | a minuscule, tilde
å | &aring; | &#229; | a minuscule, rond
ä | &auml; | &#228; | a minuscule, tréma
æ | &aelig; | &#230; | æ minuscule
ç | &ccedil; | &#231; | c minuscule, cédille
é | &eacute; | &#233; | e minuscule, accent aigu
è | &egrave; | &#232; | e minuscule, accent grave
ê | &ecirc; | &#234; | e minuscule, accent circonflexe
ë | &euml; | &#235; | e minuscule, tréma
í | &iacute; | &#237; | i minuscule, accent aigu
ì | &igrave; | &#236; | i minuscule, accent grave
î | &icirc; | &#238; | i minuscule, accent circonflexe
ï | &iuml; | &#239; | i minuscule, tréma
ñ | &ntilde; | &#241; | n minuscule, tilde

    Caractères accentués, Symboles
Caractère | Syntaxe | Syntaxe (ASCII) | Description
ó | &oacute; | &#243; | o minuscule, accent aigu
ò | &ograve; | &#242; | o minuscule, accent grave
ô | &ocirc; | &#244; | o minuscule, accent circonflexe
õ | &otilde; | &#245; | o minuscule, tilde
ö | &ouml; | &#246; | o minuscule, tréma
ø | &oslash; | &#248; | o minuscule, barré
ú | &uacute; | &#250; | u minuscule, accent aigu
ù | &ugrave; | &#249; | u minuscule, accent grave
û | &ucirc; | &#251; | u minuscule, accent circonflexe
ü | &uuml; | &#252; | u minuscule, tréma
ý | &yacute; | &#253; | y minuscule, accent aigu
ÿ | &yuml; | &#255; | y minuscule, tréma

    Vous pouvez voir l'aperçu dans votre Navigateur ou Browser, en cliquant ici. (Exemple 4)

    Fin de cette première leçon, la prochaine sera consacrée à la Structure du document HTML.


Structuration du Document HTML

Structuration du Document HTML :

<HTML> :

Tous les documents des pages Web HTML commenceront par la balise de début <HTML> et se termineront par la balise de fin </HTML>.

N'oublions pas la balise de la première ligne de début du document type qui doit commencer comme ceci <!doctype HTML> et qu'on verra les explications par la suite de nos leçons.

La structure de premier niveau du document aura donc la forme suivante :

<!DOCTYPE HTML> (1ère ligne)

<HTML>

Corps du document

. . .

</HTML>

Aperçu du premier niveau. Vous verrez une page blanche qui n'a pas de contenue, ce qui est tout à fait normal jusqu'à présent. Puisque nous n'avions pas ordonné les instructions au microprocesseur, ou que votre navigateur n'exécute pas les instructions qu'on lui donne, ce qui est très juste jusqu'à cette leçon puisque rien ne lui permette d'afficher un contenu quelconque. ...

Nous vous rappelons que pour visualiser le code HTML dans un document Web :

Il suffira de cliquer avec le bouton droit de votre souris, afin d'ouvrir le menu contextuel, puis de pointer sur "Afficher le code source de la page".

<HEAD> :

Le titre du document, les Scripts JavaScript seront généralement inclus dans une zone de prologue ou d'en-tête de la balise de début : <HEAD>. Cette zone se termine par une balise de fin </HEAD>. Nous verrons par la suite que nous pouvons trouver d'autres termes dans cette zone d'en-tête.

<!DOCTYPE HTML> (1ère ligne)

<HTML>

<HEAD>

Prologue ou d'en-tête

</HEAD>

Corps du document

. . .

</HTML>

Aperçu du premier niveau. Là encore, vous verrez une page blanche qui n'a pas de contenue, ce qui est tout à fait normal jusqu'à présent. Puisque rien ne lui permette d'afficher un contenu quelconque dans votre Browser. ...

Nous allons maintenant s'occuper de la balise de début du titre <TITLE> et de la balise de fin du titre </TITLE>

<TITLE> :

Un texte qui apparaît dans la zone titre du browser est défini par <TITLE>. Il faut noter que ce titre est souvent négligé au détriment d'une zone de titre enrichie d'images et de logos, que l'auteur situe au début du document. Le titre défini entre les balises de début <TITLE> et de fin </TITLE> a, outre un caractère informatif, au moins deux raisons d'être soigné :

  • C'est ce texte qui sera stocké dans le fichier "Bookmark" (signet) que gère le browser pour le compte du lecteur. On préférera donc un texte du style « Bienvenue chez les Policiers » à « Bienvenue », qui ne sera jamais capable de fournir une indication pertinente sur la destination.

  • Dans un contexte XWindows, lorsque l'on "iconifie" la fenêtre, c'est ce titre qui sera pris en compte comme nom par l'icône.

    • "Bookmark" : Ce fichier permet, lorsqu'on est connecté à un document, de conserver son URL dans un fichier de type annuaire afin de pouvoir s'y connecter ultérieurement d'un simple clic.

    Le titre doit être suffisamment court pour tenir entièrement dans l'espace que le Browser lui réserve, sous peine d'être tronqué et ainsi de perdre son sens.

    <!DOCTYPE HTML> (1ère ligne)

    <HTML>

    <HEAD>

    <TITLE>Bienvenue chez les Policiers</TITLE>

    </HEAD>

    Corps du document

    . . .

    </HTML>

    Aperçu du premier niveau. Là encore, vous verrez une page blanche qui n'a pas de contenue, sauf en haut de votre navigateur, ce qui est tout à fait normal jusqu'à présent.

    Aperçu de l'image selon votre navigateur comme ci-après :

    <BODY> :

    Nous allons entreprendre la balise de début <BODY> et la balise de fin de </BODY>, réside dans toutes les pages HTML des documents Web. Nous verrons par la suite qu'il y a d'autres attributs de ces mêmes balises et que, des extensions permettent de compléter l'utilisation de cette balise.

    <!DOCTYPE HTML> (1ère ligne)

    <HTML>

    <HEAD>

    <TITLE>Bienvenue chez les Policiers</TITLE>

    </HEAD>

    <BODY>

    Corps du document

    . . .

    </BODY>

    </HTML>

    Aperçu du premier niveau. Là encore également, vous verrez une page blanche qui n'a pas de contenue, sauf en haut de votre navigateur concernant le titre, ce qui est tout à fait normal jusqu'à présent.

    Aperçu de l'image selon votre navigateur comme ci-après :

    Ce dernier exemple donne la structure minimale que doit posséder tout document HTML. Dans ces exemples ci-dessus, on a présenté le code HTML, en décalant les divers niveaux de la structure. Cette indentation n'est pas obligatoire, mais elle est fortement recommandée afin de faciliter la lecture et la maintenance du code source. Les Browsers qui exécutent le code HTML ne tiennent pas compte des retours à la ligne et l'on aurait très bien pu écrire le code HTML de la façon suivante, qui aurait produit le même affichage dans le Browser :

    EXEMPLE "à ne pas faire" :

    <html> <head> <title> Bienvenue chez les Policiers </title> </head>

    <body>

    document

    . . . </body> </html>

    Voici un exemple du même aperçu dans votre Navigateur, à éviter de faire ainsi ! En cliquant ici.

    Image correspondante selon votre navigateur ci-après :

    <ADDRESS> :

    Le bloc ou balise adresse est un élément prévu pour indiquer toute information concernant l'auteur du document Web (Adresse, Téléphone, E-Mail, etc.). Il peut être inséré à n'importe quel endroit du document ou de la page HTML ; l'habitude sur le Web est de mettre cette zone adresse à la fin du document. Les Browsers affichent généralement le texte compris entre les balises de début <ADDRESS> et de fin </ADDRESS> en italique.

    EXEMPLE :

    <address>

    Jean-Claude - Tél. : 95 - 90 - 13 - 78 - 14.

    E-Mail : jeanc@orange.fr ; (le tout en minuscule).

    </address>

    Voir l'aperçu de votre Browser concernant l'adresse, en cliquant ici.

    Aperçu de l'image :

    <!-- COMMENTAIRES --> :

    Nous pensons que vous aviez pu vous rendre compte que tout texte commençant <!-- et se terminant par --> dans votre navigateur, ne sera pas interprété par le Browser, donc pas affiché. Cela sert à l'auteur du document pour commenter son fichier source.

    EXEMPLE :

    <!-- Document à ne diffuser qu'aux machines appartenant au domaine de la mécanique générale .mecanique.fr -->

    Aperçu du code source, en cliquant ici.

    Aperçu de l'image sur le (s) Browser (s) ci-après :

    ATTRIBUTS D'UNE BALISE :

    Nous verrons, au cours de l'étude des différentes balises HTML, que certaines peuvent admettre des attributs, chacun d'eux pouvant avoir une valeur. Au niveau syntaxique, le premier attribut est séparé de la balise par un espace, ainsi que les attributs entre eux. Si l'attribut doit prendre une valeur, elle est spécifiée après le signe = (égale) suivant l'attribut.

    La valeur de l'attribut sera écrite entre double guillemets ("), si cette valeur est alphanumérique.

    <balise attribut_1=numerique attribut_2="alphanumerique">

    EXEMPLE :

    <pre width="50">

    <a href="/informatique/depierre.html">

    On verra ces balises par la suite de nos leçons.

    LE DOCUMENT HTML MINIMUM :

    Nous avons maintenant défini suffisamment d'éléments de structure du langage HTML pour lister l'ossature type que nous trouverons toujours dans un document ou toutes les pages HTML de votre site :

    *** Ossature *** = Squelette, Armature, Structure, Assemblage régulier d'éléments, qui soutient un ouvrage et en assure la rigidité.

    Aperçu du code source, en cliquant ici.

    Aperçu de l'image sur le(s) Browser(s) ci-après :

    TESTER LES DOCUMENTS HTML :

    La finalité d'un fichier contenant une page HTML par exemple, et son installation dans les répertoires du serveur afin qu'il soit offert à la consultation. Ce n'est pas envisageable pendant la phase d'apprentissage du langage ou pendant la mise au point d'un document.

    On éditera donc ces fichiers HTML de test et on les stockera dans un répertoire personnel si l'on travaille sur une machine Unix, ou dans un dossier de test, si l'on travaille sur un PC ou un Macintosh.

    N.B. : On pourra utiliser n'importe quel éditeur : un bloc note, ou encore Teachtext (ancien) comme Word feront l'affaire sur un Macintosh ; cependant, si l'on prend un traitement de texte évolué comme Word, on aura soin de sauvegarder le fichier en format "TEXT".

    C'est préférable d'avoir "son propre éditeur HTML", comme Web - Expert par exemple, on vous laisse le soin de travailler avec votre éditeur que vous eûtes l'habitude ... FrontPage, que nous avions travaillé longtemps, est un très bon éditeur HTML, mais chacun à ses propres logiciels et ses inconvénients, à vous de voir ...

    Il suffit que soit installé sur cette machine d'apprentissage un logiciel client comme Opéra, Chrome ou encore Internet Explorer. Il n'est absolument pas nécessaire pendant cette période d'avoir accès à un serveur Web ni même d'être connecté au réseau.

    En effet, les Browsers offrent la possibilité d'ouvrir et d'interpréter un fichier local, "selon votre navigateur". Il suffit de cliquer sur le menu déroulant File du browser et de sélectionner l'option Open file. On reçoit alors une nouvelle fenêtre permettant de sélectionner le fichier à tester.

    MÉTHODE DE TRAVAIL :

    Voici les étapes à suivre pour tester les fichiers HTML avant de les installer dans les répertoires du serveur :

    • Appeler l'éditeur de texte,

    • Écrire le code HTML,

    • Enregistrer sous un Nom avec le suffixe .html,

    • Appeler le Browser Chrome ou autres par exemple,

    • Utiliser le menu Open file selon votre navigateur,

    • Sélectionner votre document ou page HTML, qui s'affichera dans le browser, selon votre navigateur.

    Si vous n'êtes pas satisfait ...

    • Retourner dans l'éditeur de texte sans quitter le Browser,

    • Corriger ou modifier votre code HTML,

    • Utiliser la commande reload (selon votre navigateur) et juger vos modifications.

    RÉSUMÉ DE NOS DEUX LEÇONS (PREMIÈRE ET DEUXIÈME) :

    HTML est un langage balisé où chaque balise s'inscrit entre les caractères < (inférieur à) et > (supérieur à). Les balises peuvent avoir des attributs spécifiant éventuellement des valeurs ou des caractéristiques. On ne peut pas saisir des caractères accentués directement au clavier ; il faut les remplacer par les codes HTML équivalents ; il en va de même pour certains symboles. Les délimiteurs pour ces codes sont le caractère & (et commercial) au début du code et le caractère ; (point virgule) à la fin de ce même code. Ainsi, &eacute; signifie é (e accent aigu).

    Les éléments de structure définis dans cette leçon sont de deux sortes :

    Obligatoires

    • <HTML> Premier élément encadrant tout le fichier ou de la page HTML.

    • <HEAD> Zone d'en-tête.

    • <TITLE> Définition d'un titre.

    • <BODY> Corps du document ou de la page HTML

    Optionnels

    • <ADDRESS> Bloc d'information sur l'auteur du document

    • <!--COMMENTAIRES--> Commentaires

    Fin de cette deuxième leçon, la prochaine sera consacrée aux Divisions concernant le langage HTML.


Les Divisions HTML

Tout texte technique ou scientifique est habituellement divisé selon des paragraphes subissant une numérotation hiérarchique du type ci-après : 1. 1. 1, 1. 1. 2, 1. 1. 3, 1. 2. 1, etc. La plupart des traitements de texte gèrent ces formats de numérotations automatiques, en affectant la taille des caractères d'un titre, en fonction de son niveau dans la hiérarchie.

Dans le langage HTML, encore une fois, tout est à la charge de l'auteur. Celui-ci dispose de six grosseurs de titre vont lui permettre de diviser son document ou ses pages HTML et d'un système de liste que nous verrons par la suite dans nos études.

<Hn> :

C'est la balise affectant la taille des caractères dans laquelle n varie de 1 à 6. Les plus gros ont la valeur 1 et les plus petits la valeur 6. Le texte entre ces balises est traité en caractère gras.

La balise de début et la balise de fin génèrent automatiquement un espace de type nouveau paragraphe, (passage à la ligne avec espace correspondant environ au saut d'une ligne).

Exemple :

<h1> Po&egrave;mes de Jean-Claude </h1>

<h2> Les Tulipes </h2>

Quand je vais chez le fleuriste <br>

Je n'ach&egrave;te que des Tulipes <br>

. . . .

<h4> Auteur : Jean-Claude </h4>

Pour visualiser l'aperçu, en cliquant ici. (N'oubliez pas de cliquer sur le bouton droit de votre souris afin d'ouvrir le menu contextuel, puis de pointer sur affichage "code source").

Image correspondante au code source :

Jusqu'à présent, rien de compliqué concernant le code source HTML. Il suffit de bien retenir les mots clés.

<BR> :

Lorsqu'on exécute du code HTML, les browsers traitent le texte au kilomètre dans la largeur de leur fenêtre et ignorent le découpage en ligne tel qu'il existe dans le fichier source. La longueur des lignes sera donc fonction de la taille que fixe le lecteur en dimensionnant la fenêtre de son browser. Il appartient à l'auteur du document de provoquer, lorsqu'il le souhaite, un passage à la ligne. La balise <BR> qui génère ce passage est une balise vide, c'est-à-dire qu'il n'y a pas de balise de fin (</BR> ne s'utilise pas).

Exemple :

Quand je vais chez le fleuriste, <br> je m'ach&egrave;te que des Tulipes que j'adore ! <br>

Si ma chanson

chante triste. <br> C'est que l'amour n'est plus l&agrave; !!!

Auteur : <h4> Pierrot la Tulipe </h4>

Pour visualiser l'aperçu, en cliquant ici.

Le retour à la ligne derrière la phrase « Si ma chanson », sera ignoré par le browser. En revanche, l'absence de balise <BR> derrière la phrase « C'est que l'amour n'est plus là. » n'est pas gênante car la balise <H4> va provoquer un retour à la ligne et un espacement inter-paragraphe.

<P> :

La balise <P> provoque le passage au paragraphe suivant. Nous verrons par la suite que cette balise peut être comptée ou complétée par de nombreux attribus. Tout comme <BR>, cette balise est généralement considérée comme une balise vide, bien qu'il soit tout à fait valide de terminer un paragraphe par </P>.

<P> est différent de <BR> : elle provoque un passage à la ligne et décale la ligne suivante d'un espace d'environ une ligne (espacement inter-paragraphe).

N.B. : C'est préférable de mettre une balise de fin </P> afin de rendre le code plus agréable et plus compréhensible de façon, en cas de maintenance, cela rendra plus facile de mettre de l'ordre dans son code source.

Pour visualiser l'aperçu ci-dessous, en cliquant ici.

Exemple :

<h3> Le grand homme </h3>

Chez un tailleur de pierre <br> o&ugrave; je l'ai rencontr&eacute; <br>

il faisait prendre ses mesures <br> pour la post&eacute;rit&eacute;.

<p> Auteur : Jean-Pierre </p>

<HR> :

C'est une balise de division graphique qui provoque un trait horizontal sur toute ou partie de la largeur de la fenêtre du browser.

Exemple :

<h3> Le grand homme </h3>

Chez un tailleur de pierre <br> o&ugrave; je l'ai rencontr&eacute; <br>

il faisait prendre ses mesures <br> pour la post&eacute;rit&eacute;. <hr>

<p> Auteur : Jean-Pierre </p>

Pour visualiser l'aperçu, en cliquant ici.

Ce qui donne ceci :

D'autres attributs permettent de régler certains paramètres de cette balise <HR> :

L'attribut SIZE :

Il définit en pixels l'épaisseur du trait <HR SIZE=valeur>.

Pour visualiser l'aperçu, en cliquant ici.

L'attribut WIDTH :

Définit soit en pourcentage de la largeur de la fenêtre, soit en valeur absolue (pixels), la longeur du trait horizontal <HR WIDTH=valeur>.

Exemple :

<HR WIDTH=50%> <HR WIDTH=100>

Pour visualiser l'aperçu, en cliquant ici.

L'attribut ALIGN :

Dans le cas où l'on spécifie une longueur du trait inférieure à 100%, cela permet de positionner le trait horizontalement dans la fenêtre du browser <HR ALIGN=valeur>. Les valeurs possibles sont LEFT (positionnement à gauche), RIGHT (positionnement à droite), CENTER (positionnement au centre, valeur prise par défaut).

Exemple :

<HR WIDTH=50% ALIGN=LEFT>

Pour visualiser l'aperçu, en cliquant ici.

L'attribut NOSHADE :

Permet de supprimer l'effet de relief du trait horizontal.

Exemple :

<HR WIDTH=75% SIZE="8" NOSHADE>

Pour visualiser l'aperçu, en cliquant ici.

<PRE> :

Cette balise <PRE> permet de respecter la mise en page précise d'un texte ou d'une portion de texte, de la façon dont elle a été définie dans le fichier HTML.

Le browser interprète ce texte préformaté à l'aide d'une police de caractères non proportionnelle, ce qui autorise des alignements de type tableau.

Exemple :

<HTML>

<HEAD>

<TITLE> Tableau pr&eacute;format&eacute; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de tableau en texte pr&eacute;format&eacute; (&lt; pre&gt;) </H2>

<PRE>

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

| LUNDI | MARDI | MERCREDI | JEUDI | VENDREDI | SAMEDI | DIMANCHE |

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</PRE>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Ce qui nous donne ceci :

Les espaces consécutifs sont préservés à l'inverse du texte situé en dehors de ces balises où plusieurs espaces sont compactés en un seul.

On utilisera pas de balise de mise en page dans un bloc préformaté (<BR>, <P> <H>, etc.) et on évitera le caractère de tabulation. En revanche, il est tout à fait permis d'inscrire des liens vers d'autres documents ou pages HTML. (Concernant les liens, on verra cela par la suite de nos études).

La balise <PRE> admet l'attribut WIDTH qui permet de fixer le nombre de colonnes dans lesquelles se situe le texte non formaté (<PRE WIDTH=40> par exemple). Si cet attribut est absent, la valeur prise par défaut est 80 colonnes. Cet attribut n'est pas interprété par tous les browsers.

RÉSUMÉ DE CETTE TROISIÈME LEÇON :

Les balises suivantes permettent de structurer le document par l'adjonction de titres de diverses tailles et le réglage de la longueur des lignes et des paragraphes :

  • <Hn> Avec n = 1 à 6 où 1 est la taille maximale des caractères. Un espacement vertical de type paragraphe est généré par ces balises.

  • <BR> Force un retour à la ligne.

  • <P> Déclenche le passage au paragraphe suivant.

  • <HR> Permet de tracer un trait horizontal en travers de la page, avec différents réglages rendus possibles par les attributs :

  • <SIZE> Règle l'épaisseur du trait (en pixels).

  • <WIDTH> Règle la longueur du trait horizontal soit relativement à la largeur de la page (%), soit en valeur absolue (pixels).

  • <ALIGN> Positionne le trait à droite, à gauche ou au centre (RIGHT, LEFT, CENTER) dans le cas où il est inférieur à la largeur de la page.

  • <NOSHADE> Supprime l'effet 3D du trait.

  • <PRE> Permet de conserver le formatage du texte délimité par cette balise tel qu'il a été saisi dans le fichier source HTML.

Fin de cette troisième leçon, la prochaine sera consacrée aux Listes concernant le langage HTML.


Les Listes HTML

Les Listes HTML :

La liste est un élément important dans la structuration d'un document ; elle permet d'organiser tout ou partie d'un document pour le rendre perceptible au lecteur de la façon la plus claire possible. Les listes pourront donc être utilisées pour diviser le document aussi bien que pour effectuer des énumérations d'objets. Mais à l'inverse des traitements de texte comme Word ou FrameMaker et autres, il n'y a pas de numérotation automatique pour des niveaux hiérarchiques différents :

HTML définit deux types de listes :

  • Des listes descriptives, de type glossaire,

  • des listes régulières avec ou sans numérotation.

LISTE DESCRIPTIVE :

<DL> :

L'élément <DL> ouvre une liste descriptive. Il définit le début de la liste et englobe deux autres balises (<DT> et <DD>), dont le rôle est de caractériser, de désigner chacun des éléments, la partie définition et l'élément lui-même.

L'attribut COMPACT associé à la balise <DL> (<DL COMPACT>) permet à certains browsers d'afficher sur la même ligne l'élément et la première ligne du bloc de description.

La fin de la liste sera caractérisée par la balise de fin </DL>.

<DT> :

L'élément <DT> précède chaque item de la liste, celui-ci ne devant pas excéder une ligne. Il est à noter que le système de liste ne gère pas automatiquement la mise en relief des caractères de l'item. Il appartient à l'auteur du document d'utiliser des balises de styles (qu'on verra par la suite de nos études) ou du titre (<Hn>) pour effectuer cette opération.

Cette balise est une balise vide, donc, pas de balise de fin.

<DD> :

La balise <DD> correspond à la zone de définition de l'item. La taille de cette zone n'est pas limitée et chacune des lignes sera décalée vers la droite. Cette balise est vide.

La structure de ce modèle de liste sera donc la suivante :

<DL>

<DT> Identification de l'élément <DD> Description de l'élément.

<DT> . . . <DD> . . .

</DL>

Exemple :

<HTML>

<HEAD>

<TITLE> Listes &lt;DL&gt; </TITLE>

</HEAD>

<BODY>

<H2> GLOSSAIRE (Exemple de liste de type d&eacute;finition (&lt; DL COMPACT &gt;) ) </H2>

<DL COMPACT>

<DT> ASCII <DD> Jeu de caract&egrave;res qui assigne des valeurs num&eacute;riques standard

aux lettres, chiffres et signes de ponctuations.

<DT> EPS <DD> Format de description de fichiers PostScript, ou PostScript-encapsul&eacute;.

<DT> POLICE <DD> Assortiment de styles que poss&egrave;de une cat&eacute;gorie de

caract&egrave;res (gras, italique, etc. ...).

</DL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. (N'oubliez pas de cliquer sur le bouton droit de votre souris afin d'ouvrir le menu contextuel, puis de pointer sur affichage "code source").

LISTES RÉGULIÈRES :

<LI> :

La balise <LI> est vide et commune à tous les types de listes restants. Elle précédera chaque objet de la liste.

<LH> :

Commune aussi à l'ensemble des listes, cette balise vide permet d'affecter un en-tête à l'ensemble de la liste. Le texte associé apparaît de façon identique aux items mais n'est pas précédé de puce ou de numéro. La syntaxe générale des listes sera :

< Balise d'ouverture >

<LH> Élément d'en-tête

<LI> Élément de l'énumération

<LI> . . . et ainsi de suite . . .

< Balise de fermeture >

<UL> :

La balise <UL> permet de générer des listes non numérotées. Chacun des éléments de la liste sera précédé d'une puce, dont le graphisme pourra varier selon le niveau d'imbrication de la liste.

Exemple :

<HTML>

<HEAD>

<TITLE> Listes &lt; UL &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type non ordonn&eacute;e (&lt; UL &gt;) </H2>

<UL>

<LH> <b> R&eacute;pertoires </b> <P>

<LI> Fichiers HTML

<LI> Fichiers images

<LI> Fichiers sons

<LI> Fichiers films

<LI> Fichiers test

<LI> Fichiers exemples

<LI> Fichiers informatiques

<LI> Fichiers &eacute;lectroniques

<LI> *** Ainsi de suite ***

</UL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

L'attribut TYPE dans les listes non ordonnées :

Cet attribut permet de contrôler le symbole (la puce) précédant chacun des items de la liste. Il peut être utilisé avec la balise <UL> ; il définit alors le symbole pour toute la liste, sauf s'il apparaît dans une balise <LI> où il redéfinit un nouveau symbole pour le reste de la liste.

<OL TYPE=valeur>

<LI> TYPE=valeur>

Les valeurs définissant la puce peuvent être ainsi :

  • square, qui donne à la puce l'aspect d'un rectangle,

  • circle, qui donne à la puce l'aspect d'un cercle vide,

  • disc, qui donne à la puce l'aspect d'un cercle plein.

Exemple :

<HTML>

<HEAD>

<TITLE> Liste - type </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type non num&eacute;rot&eacute;e avec TYPE </H2>

<UL TYPE=CIRCLE>

<LH ID=lang> <i> Langages et formats </i> <p>

<li> HTML

<li> VRML

<li type=square> PDF

<li type=disc> JavaScript

<li> Java

<li type=square> Informatique

<li type=square> &Eacute;lectrotechnique

<li> &Eacute;lectronique

</UL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Emboîtement de listes non ordonnées :

Dans l'exemple suivant, certains browsers utilisent trois puces différentes, (par exemple : le Netscape), en fonction du degré d'emboîtement, puis ils utilisent la dernière puce (le carré vide) pour tous les niveaux suivants.

Pour visualiser l'aperçu, en cliquant ici.

Aperçu de l'image du code source ci-après :

<OL> :

La balise <OL> s'utilise pour une liste ordonnée ou numérotée. Chaque balise <LI> inclue dans un ensemble <OL> va incrémenter le nombre qui sera affiché devant l'élément de la liste.

Exemple :

<HTML>

<HEAD>

<TITLE> Listes &lt; OL &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type ordonn&eacute;e (&lt; OL &gt;) </H2>

<OL>

<li> Fichiers HTML

<li> Fichiers images

<li> Fichiers sons

<li> Fichiers films

<li> Fichiers test

<li> Fichiers exemples

<li> Fichiers histoires

<li> Fichiers math&eacute;matiques

<li> *** Ainsi de suite ***

</OL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

L'attribut TYPE dans les listes ordonnées :

Par défaut, les listes sont numérotées en chiffres arabes. D'autres types de numérotation sont possibles, en ajoutant l'attribut TYPE à la balise <OL> :

<OL TYPE=valeur>

  • La valeur 1 produit une numérotation en chiffres arabes (1, 2, 3, . . .) (valeur par défaut),

  • La valeur A produit une numérotation en lettres capitales (A, B, C, . . .),

  • La valeur a produit une numérotation en lettres minuscules (a, b, c, . . .),

  • La valeur I produit une numérotation en chiffres romains (I, II, III, IV, . . .),

  • La valeur i produit une numérotation en chiffres romains minucules (i, ii, iii, iv, . . .).

L'attribut START dans les listes ordonnées :

Ajouté à la balise <OL>, il permet de définir la valeur de départ de la liste.

<OL START=valeur>

La valeur donnée sera toujours numérique quel que soit le type, alphabétique ou romain.

L'attribut VALUE :

Cet attribut s'applique à la balise <LI>. Il permet de rompre le séquencement et de le réinitialiser à une nouvelle valeur.

<LI VALUE=valeur>

La valeur donnée sera toujours numérique quel que soit le type, alphabétique ou romain.

Exemple :

<HTML>

<HEAD>

<TITLE> Liste - Type-Start-Value </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type num&eacute;rot&eacute;e en romain minuscule </H2>

<OL type=i start=3>

<li> Fichiers HTML

<li> Fichiers images

<li> Fichiers sons

<li> Fichiers films

<li> Fichiers test

<li> Fichiers exemples

<li> Fichiers histoires

<li> Fichiers math&eacute;matiques

<li> *** Ainsi de suite ***

</OL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Exemple 2 :

<HTML>

<HEAD>

<TITLE> Listes Alphab&eacute;tiques </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type alphab&eacute;tique en lettres capitales </H2>

<OL type=A >

<li> Fichiers HTML

<li> Fichiers images

<li> Fichiers sons

<li> Fichiers films

<li> Fichiers test

<li> Fichiers exemples

<li> Fichiers histoires

<li> Fichiers math&eacute;matiques

<li> *** Ainsi de suite ***

</OL>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Emboîtement de listes ordonnées :

Comme cela a été précisé au début de cette leçon, l'exemple suivant montre qu'il n'y a pas de numérotation automatique selon le degré d'emboîtement.

Exemple :

<HTML>

<HEAD>

<TITLE> Listes &lt;OL&gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de liste de type ordonn&eacute;e (&lt;OL&gt;) </H2>

<ol>

<li> Fichiers HTML </li>

<li> Fichiers images </li>

<li> Fichiers sons </li>

<li> Fichiers films </li>

<li> Fichiers test </li>

<ol>

<li> Fichiers exemples

<li> Fichiers histoires

<li> Fichiers math&eacute;matiques

<ol>

<li> Natures mortes

<li> Paysages

<ol>

<li> Et&eacute;

<li> Hiver

</ol>

<li> Personnages

</ol>

<li> Fichiers travaux

</ol>

<li> Fichiers personnels

<li> Fichiers physiques </li>

</ol>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Listes imbriquées :

L'exemple suivant présente des listes à plusieurs niveaux. Encore une fois, l'indentation dans le code source HTML n'est pas obligatoire. mais cependant, lorsque la structure devient de plus en plus complexe, une telle écriture facilite la maintenance des fichiers lorsque ces derniers sont respectés concernant l'indentation des pages HTML ou encore PHP que l'on verra plus tard.

Exemple :

<HTML>

<HEAD>

<TITLE> Listes imbriqu&eacute;es </TITLE>

</HEAD>

<BODY>

<H2> Exemple de listes de type imbriqu&eacute;es </H2>

<ul>

<li> Fichiers HTML </li>

<li> Fichiers images </li>

<li> Fichiers sons </li>

<li> Fichiers films </li>

<ol>

<li> Fichiers test </li>

<ul>

<li> Fichiers exemples

<li> Fichiers histoires

<li> Fichiers math&eacute;matiques

</ul>

<li> Natures mortes

<li> Paysages

<ul>

<li> Et&eacute;

<li> Hiver

</ul>

<li> Fichiers du serveur

<li> Fichiers des t&eacute;l&eacute;viseurs

</ol>

<li> Fichiers travaux

<li> Text 1.html

<li> Text 2.html

<li> Text 3.html

<li> Fichiers personnels

<li> Fichiers physiques

<li> Fichiers g&eacute;om&eacute;tries

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Nous résumons cette leçon ci-après :

Principaux types de listes :

  • Listes descriptives :

<DL> Ouverture de la liste.

<DT> Titre de l'élément n <DD> Description de l'élément n.

<DT>Titre de l'élément n + 1 <DD> Description de l'élément n + 1.

</DL> Fermeture de la liste.

  • Listes non numérotées :

<UL> Ouverture de la liste.

<LI> Élément de la liste.

<LI> . . .

</UL> Fermeture de la liste.

  • Listes numérotées :

<OL> Ouverture de la liste.

<Li> Élément de la liste.

<LI> . . .

</OL> Fermeture de la liste.

La balise <OL> admet deux attributs :

  • <TYPE> pour définir la numérotation, 1 pour chiffre, A pour alphabétique majuscule, a pour alphabétique minuscule, I pour romain majuscule et i pour romain minuscule.

  • <START> pour définir la valeur de départ de la liste.

Utilisée dans un bloc <OL>, la balise <LI> admet l'attribut VALUE, qui permet à l'intérieur de la liste de modifier le séquencement.

Les balises <UL> et <LI> admettent l'attribut TYPE qui permet de définir la puce située devant l'item. Les valeurs permises sont SQUARE pour sélectionner un carré, CIRCLE pour sélectionner un cercle vide et DISC pour un cercle plein. Lorsque l'attribut TYPE est définit dans la balise <LI>, il modifie la valeur définie dans la balise <UL> pour le reste de la liste.

Fin de cette quatrième leçon, la prochaine sera consacrée aux Styles concernant le langage HTML.


Les Styles HTML

Les Styles HTML :

Nous allons maintenant étudier les balises correspondantes aux balises de base du langage permettant d'intervenir sur la présentation des pages concernant le langage HTML. Il ne faut pas oublier, cependant, que les Internautes a toute latitude pour modifier cette présentation en intervenant sur le paramétrage de leurs browsers ; ils peuvent déjà agir sur la taille, la couleur et le choix des polices. Ils pourront bientôt créer localement sur leurs machines ces propres styles de présentation. Ces balises pourront notamment être utilisées dans les définitions de feuilles de styles que nous verrons au cours de nos études.

HTML définit deux méthodes pour la présentation des caractères : le Style physique et le Style logique.

Style physique ou Style des caractères :

Les balises suivantes vont explicitement indiquer le type de caractères à utiliser.

<B> :

Cette balise commence un texte, en caractères gras et doit se terminer par la balise de fin </B>, comme nous l'avions expliqué dès le début de notre première leçon.

<I> :

Cette balise commence un texte, en caractères italiques et doit se terminer par la balise de fin </I>.

<U> :

Cette balise commence un texte, en caractères soulignés (elle n'est pas reconnue par tous les browsers), et elle doit se terminer par une balise de fin </U>.

<TT> :

Cette balise permet de formater le texte, en caractères de type machine à écrire (télétype), et elle doit se terminer par une balise de fin </TT>. La police utilisée est de type non proportionnelle.

N.B. : Avec une police non proportionnelle, l'espace occupé par chaque caractère est constant. Ainsi la lettre I occupe la même largeur que la lettre M. cela permet notamment de réaliser des alignements pour les tableaux.

Exemple :

<HTML>

<HEAD>

<TITLE> LE BIOS </TITLE>

</HEAD>

<BODY>

<P><font face="Arial" size="3" color="#000000"> <b> LE BIOS : </b> <i> (<b>B</b>asic <b>I</b>nput <b>O</b>utput <b>S</b>ystem)</i>. Programme de base d'un ordinateur qui renferme toutes les informations d&eacute;finissant les param&egrave;tres de fonctionnement des &eacute;l&eacute;ments du PC, notamment ceux de la carte m&egrave;re. Int&eacute;gr&eacute; dans une m&eacute;moire sp&eacute;cifique de la carte m&egrave;re, il peut &ecirc;tre actualis&eacute; pour b&eacute;n&eacute;ficier des changements de version.</P> <P> Vous voyez sur l'&eacute;cran la page <TT> telle qu'elle sera <u> imprim&eacute;e</u>.</TT></font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

A noter : Vous vous apercevez que certaines phrases ci-dessus sont encodées, il n'en est rien ! Il suffit de bien connaître les mots clés ainsi que les encodages, qui se trouve au début de nos leçons : Voir les encodage, en bas de page.

Style logique, Style de paragraphe :

Comme précédemment, l'interprétation par le browser des consignes concernant le style des paragraphes est tout à fait libre, et les huit styles logiques définis dans HTML pour caractériser des portions de texte ne produiront pas forcément autant de représentations différentes. Il est néanmoins préférable d'utiliser ce balisage, en choisissant le mode le mieux adapté au genre du texte : balise de citation pour une citation, balise de code pour un exemple de programme informatique, etc. Se conformer à cette règle est une garantie de bonne exploitation des fichiers HTML pour les futurs browsers.

<CITE> :

Cette balise est souvent utilisée pour citer un ouvrage ou une référence plutôt qu'une citation, pour laquelle on préférera la balise <BLOCKQUOTE> ; des caractères italiques sont le plus souvent choisis par le browser.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; CITE &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; CITE &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<CITE>

<P> <font face="Arial" size="3" color="#000000"> <b> BUFFERIS&Eacute; : </b> Indique qu'un circuit num&eacute;rique est muni d'un BUFFER ce qui augmente sa sortance ou facteur pyramidal. Peut indiquer &eacute;galement qu'un circuit comporte une m&eacute;moire tampon. </font></P>

</CITE>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<CODE> :

La balise <code> est utilisée pour un exemple de programme informatique ; des caractères de type machine à écrire avec police non proportionnelle (fonte Courier) seront adoptés.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; CODE &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; CODE &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<CODE>

<P> <font face="Arial" size="3" color="#000000"> <b> BUFFERIS&Eacute; : </b> Indique qu'un circuit num&eacute;rique est muni d'un BUFFER ce qui augmente sa sortance ou facteur pyramidal. Peut indiquer &eacute;galement qu'un circuit comporte une m&eacute;moire tampon. </font></P>

</CODE>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<DFN> :

On utilise <DFN> pour la définition d'un terme. Selon le browser, des caractères standard, gras ou gras italiques seront utilisés.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; DFN &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; DFN &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<DFN>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</DFN>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<EM> :

La balise <EM> permet de mettre en valeur un texte ; des caractères italiques seront le plus souvent utilisés.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; EM &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; EM &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<EM>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</EM>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<KBD> :

La balise <KBD> permet d'illustrer une saisie au clavier ; des caractères de type machine à écrire avec police non proportionnelle (une fonte Courier) seront sélectionnés.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; KBD &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; KBD &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<KBD>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</KBD>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<SAMP> :

Pour un exemple de texte, on utilise la balise <SAMP>; des caractères type machine à écrire avec police non proportionnelle (une fonte Courier) seront généralement utilisés.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; SAMP &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; SAMP &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<SAMP>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</SAMP>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<STRONG> :

Pour mettre un texte très fortement en valeur, on utilise la balise <STRONG> ; utilisation de caractères gras.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; STRONG &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; STRONG &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<STRONG>

<P> <font face="Arial" size="3" color="#000000"> AMPLIFICATEUR : Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</STRONG>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<VAR> :

Cette balise <VAR> est utilisée pour représenter une variable dans un contexte informatique par exemple, utilisation de caractères italiques.

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; VAR &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; VAR &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<VAR>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</VAR>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<BLOCKQUOTE> :

Cet élément, si l'on respecte la sémantique du langage HTML, serait plutôt à classer avec les balises <PRE> de texte préformaté et <ADDRESS> spécifiant un bloc d'adresse ou de signature. Ce sont véritablement les trois balises de formatage de paragraphe.

<BLOCKQUOTE> peut être utilisé dans le même esprit que la balise <CITE>, mais des caractères standard seront utilisés, le bloc de texte sera entièrement décalé vers la droite et des espaces de type paragraphe seront générés de part et d'autre du bloc

Exemple :

<HTML>

<HEAD>

<TITLE> La balise &lt; BLOCKQUOTE &gt; </TITLE>

</HEAD>

<BODY>

<H2> Exemple de la balise &lt; BLOCKQUOTE &gt; </H2>

<H3> Texte pr&eacute;c&eacute;dent la balise : </H3>

<BLOCKQUOTE>

<P> <font face="Arial" size="3" color="#000000"> <b> AMPLIFICATEUR : </b> Circuit permettant d'augmenter l'amplitude d'une grandeur physique. </font></p>

</BLOCKQUOTE>

<P> <font face="Arial" size="3" color="#000000"> Texte suivant la balise. </font></P>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Nous résumons cette cinquième leçon ci-après :

Le style physique :

  • <B> pour des caractères gras ;

  • <I> pour des caractères italiques ;

  • <U> pour des caractères soulignés ;

  • <TT> pour des caractères machine à écrire.

Ces styles ci-dessus sont combinatoires entre eux.

Le style logique :

  • <CITE> pour citer un ouvrage par exemple : CITATION ;

  • <CODE> pour un exemple de programme informatique : Programme informatique ;

  • <DFN> pour une définition : Amplificateur par exemple ;

  • <EM> pour un mot étranger : BIOS par exemple ;

  • <KBD> pour simuler la saisie d'un texte au clavier : Jean peut partir en vacances, il a bien travaillé ! ;

  • <SAMP> pour citer un texte par exemple : Jean peut partir en vacances, il a bien travaillé ! ;

  • <STRONG> pour mettre en valeur par exemple : Jean peut partir en vacances, il a bien travaillé ! ;

  • <VAR> pour représenter une variable par exemple : $A, $B, $C, $D, ainsi de suite ... .

Le style des paragraphes :

  • <BLOCKQUOTE> pour une citation par exemple :
    Jean peut partir en vacances, il a bien travaillé !

  • <ADDRESS> pour une adresse, une signature :
    Jean-Paul, Daniel, Pierre, etc. ...

  • <PRE> pour respecter le texte tel qu'il a été saisi, par exemple :
     Jean peut partir en vacances, il a bien travaillé !

Fin de cette cinquième leçon, la prochaine sera consacrée aux liens hypertextuels concernant le langage HTML.


Les Liens Hypertextuels HTML

Les Liens Hypertextuels HTML :

Dans les leçons précédentes, au cours de nos études étaient essentiellement axés sur la préparation d'un document, sa structuration et sa présentation que nous avions étudié jusqu'à présent. Nous arrivons maintenant au chapitre de cette leçon essentielle sur les liens hypertextuels du Web.

Les Internautes explorent un document sur le Web, en cliquant sur des zones actives, faisant ainsi apparaître de nouveaux documents. Dans HTML, une zone active peut correspondre à un caractère, un mot ou un groupe de mots, une image ou une portion d'image. Le principe sera toujours identique : associer à cette zone active, l'URL est le protocole d'adressage des documents qui se substitueront au document affiché lorsque l'on cliquera sur cette zone.

Prenons un exemple de la figure 1, lorsque l'on clique sur le mot tableaux, le système va rechercher le document à l'adresse qui est associée à ce mot, http://.../aide/tableaux.html, la page Aide s'efface pour être remplacée par la page tableaux. On dit couramment que le mot tableaux dans la page aide.html est un pointeur sur la page tableaux.html.

Un pointeur peut être placé n'importe où dans le texte. Ce peut être un élément d'une liste, ou du texte courant ; il peut être enrichi d'attributs de style physique, logique ou de paragraphe. Cependant, il n'est pas nécessaire de lui affecter un attribut pour le faire reconnaître en tant que tel : sans paramétrage spécial du browser par l'utilisateur, les liens activables sont automatiquement mis en relief (couleur et soulignement le cas échéant).

Le langage HTML définit la notion importante d'ancre pour spécifier le départ et l'arrivée d'un lien hypertexte.

  • L'ancre de départ est la zone active sur laquelle vont cliquer les Internautes pour appeler une nouvelle page. Dans l'exemple de la figure 2, les mots textes, tableaux, équations, graphiques, électroniques, informatiques et impressions sont des ancres de départ.

  • L'ancre d'arrivée est une zone inactive spécifiant le point d'arrivée d'un lien hypertexte. C'est donc une adresse de destination. Dans l'exemple de la figure 2, http://www./aide/tableaux.html est l'ancre d'arrivée de la zone cliquable tableaux. Dans ce cas, la destination est le fichier tableaux.html et il s'agit d'un lien externe, car "l'ancre de départ et l'ancre d'arrivée appartiennent à des fichiers différents".

Il existe un autre type d'ancre d'arrivée, lorsque la zone cliquable d'un document provoque un déplacement dans le même fichier, on parle alors de microtexte, car l'ancre de départ et l'ancre d'arrivée se situent dans le même fichier. Sur la figure 2, tableaux représente toujours une ancre de départ et Faire des tableaux est une ancre d'arrivée. Cette ancre d'arrivée ne comporte pas d'attributs visuels et n'est évidemment pas une zone cliquable, d'où son nom ancre inactive.

Les liens internes sont très intéressants lorsqu'un document est trop long pour tenir totalement dans la fenêtre du browser. Cela permet de se déplacer d'autant plus rapidement dans le document que celui-ci, lu en une seule fois, se trouve dans la mémoire de l'ordinateur.

Pour spécifier une ancre de départ ou une ancre d'arrivée, on utilisera la même balise.

Définition d'une ancre.

<A> :

Cette balise ne sera jamais utilisée seule.

L'attribut HREF, ancre de départ vers un lien externe :

Il s'agit ici de créer un lien vers un serveur situé quelque part sur l'Internet, ou sur un document proposé par ce serveur. Par exemple, dans une page du serveur de la ville de Nanterre, on trouvera un lien sur le fichier du serveur de chez Daniel ROBERT proposant des leçons d'électroniques et informatiques totalement gratuites.

La balise <A> spécifie l'attribut HREF dont la valeur précise l'URL du document à atteindre :

  • <A HREF="url_de_destination">zone_cliquable_avec_attributs_visuels</A>

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> &Eacute;lectronique </TITLE>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000"> Tout courant &eacute;lectrique dans un conducteur est d&ucirc; &agrave un d&eacute;placement d'&eacute;lectrons.<A HREF="http://www.electronique-et-informatique.fr/Electronique-et-Informatique/index.php">Durant leur d&eacute;placement</A>, ces &eacute;lectrons rencontrent des obstacles d&ucirc; aux atomes du conducteur . . . </font></p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Concernant l'ancre, "Durant leur déplacement", sera mise en évidence par les attributs visuels en vigueur sur le browser, et, lorsque l'on cliquera dessus, on effectuera une connexion vers le serveur Web.

Dans l'exemple ci-dessus, l'URL précise un sommaire particulier ou un fichier du serveur ; si l'on souhaite arriver directement sur la home page d'un serveur (qui n'est autre qu'un fichier HTML pris par défaut, généralement index.html ou index.htm), l'URL sera alors composée uniquement du nom du serveur ou encore le nom du Domaine :

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> &Eacute;lectronique-Informatique </TITLE>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000">Le <A HREF="http://www.electronique-et-informatique.fr/">centre</A> est le laboratoire d'&eacutelectronique de chez Daniel qui essaye d'apporter des solutions &agrave; tous probl&egrave;mes de certains Internautes dans le domaine d'informatique ainsi que l'&eacute;lectronique &eacute;galement.</font></p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Nous attirons votre attention que HTTP est le nom d'un protocole, tandis que electronique-et-informatique.fr est le nom d'un Domaine à laquelle que le fichier index.html ou index.htm est inséré dans ce Domaine, c'est pourquoi que, lorsque l'on clique sur le lien hypertextuel que l'on va directement sur la page d'accueil ou home page.

A noter : dans l'URL, il ne faut en aucun cas, pas d'espaces ni de ponctuations, ce qui pourrait provoquer un dysfonctionnement de cette dernière pour accéder à la page concernée, par exemple, home page.

Par lien hypertexte externe, on entend un lien vers un fichier autre que celui couramment en exécution.

Dans un même serveur se trouvent les fichiers aide.html et graphique.html. Dans le fichier aide.html, on trouve un lien vers le fichier graphique.html et un lien vers https://www.google.fr et un autre lien vers http://www.microsoft.com. Ces trois liens sont considérés comme externes.

L'attribut HREF, ancre de départ vers un lien interne :

Dans ce cas, on se propose de mettre un lien hypertexte vers un point précis du fichier en cours d'exécution : par exemple, à la ligne 40 du fichier, on propose un lien pour sauter directement à la ligne 90. Il faut donc placer une ancre active (ancre de départ) à la ligne 40 et une ancre inactive (ancre d'arrivée) à la ligne 90.

<A HREF="#etiquette">Zone_cliquable_avec_attributs_visuels</A>

L'ancre de départ est ainsi définie que l'on verra par la suite de nos études.

L'attribut HREF, ancre de départ vers un point spécifique d'un lien externe :

On référence dans ce cas une entrée particulière d'un document externe :

<A HREF="url_destination#etiquette">zone_cliquable_avec_attributs_visuels</A>

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Ancre de D&eacute;part </TITLE>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000">Le <A HREF="http://electronique-et-informatique.fr/Electronique-et-Informatique/Digit/Proc_ordi/Complements_Micros/Glossaire_de_A_a_H.php#B">centre est le laboratoire d'&eacutelectronique de chez Daniel</A> qui essaye d'apporter des solutions &agrave; tous probl&egrave;mes de certains Internautes dans le domaine d'informatique ainsi que l'&eacute;lectronique &eacute;galement.</font></p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

A noter : #B est une ancre qui va à un endroit précis de notre site, c'est-à-dire à la lettre B.

L'attribut NAME, ancre d'arrivée :

<A NAME="label">Zone_NON_cliquable_SANS_attributs_visuels</A>

Définit l'ancre d'arrivée, lieu que l'on atteindra, en cliquant sur une ancre de départ.

On notera dans l'ancre de départ, le caractère # (dièse) qui indique que la référence hypertexte n'est pas une URL, mais une étiquette.

L'attribut HREF et NAME sur une même ancre ;

Application concernant la note de bas de page :

Une ancre peut admettre simultanément plusieurs attributs. Nous allons utiliser l'analogie avec une note de bas de page dans un texte imprimé pour étudier l'utilisation des attributs <HREF> et NAME spécifiés sur le même ancre.

La note de bas de page est indiquée par un petit chiffre en exposant, invitant les Internautes à déplacer ses yeux vers le bas de la page pour lire une explication complémentaire ; ensuite, il faut retrouver ce petit chiffre dans la page pour poursuivre la lecture.

A l'inverse d'un document papier, une page HTML peut être très longue et par conséquent ne pas être complètement affichée dans l'espace du browser. Si l'on souhaite simuler un type d'annotation comme la note de bas de page dans une page Web, on peut placer à la fin du document cette "note" précédée d'une ancre passive (attribut NAME), et au fil du texte, y faire référence en plaçant une ancre active (attribut HREF). Cette méthode fonctionnera très bien et les Internautes, lorsqu'ils cliqueront sur l'ancre active, provoqueront bien le saut vers la note.

Il reste maintenant à lui assurer un retour aisé vers le point d'interruption de sa lecture de chacun de nous, car ce point n'est plus affiché à l'écran du moniteur si la page HTML est longue.

Nous coderons le document de la façon suivante :

  • dans le texte courant, on place une ancre active et passive de la forme ci-après :

    . . . <A HREF="note_1" NAME="retour_1"> (1) </A> . . .

  • de même en-tête du bloc de texte composant la note :

    <A HREF="retour_1" NAME="note_1"> (2) </A> Texte de la note . . .

Ainsi, les Internautes peuvent cliquer sur l'ancre (1), vont lire l'annotation, puis ils peuvent cliquer sur l'ancre (2) et retrouvent le fil de leur lecture.

Remarquez bien, entre les ancres (1) et (2) sont totalement inversées par rapport au note_1 et au retour_1 concernant les A HREF et NAME.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Note de bas de page </TITLE>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000"> Pour illustrer le fonctionnement de la note de bas de page <A HREF="#note_1" NAME="retour_1"> <b> (1) </b> </A> il est n&eacute;cessaire, comme le document est <b> court </b> de r&eacute;duire la taille de la fen&ecirc;tre du browser &agrave; quelques lignes et &agrave; quelques colonnes. (5 ou 6 lignes de 40 caract&egrave;res mais, nous allons quand m&ecirc;me mettre un peu plus de textes et interparagraphes seront plus long et plus espac&eacute;s entre eux, et nous mettons &eacute;galement une image ou un sch&eacute;ma &eacute;lectronique, afin de provoquer un ascenseur sur certains de vos browsers pour que le programme fonctionne correctement. </font> </p>

<p> <font face="Arial" size="3" color="#000000"> Convertir des signaux analogiques en signaux num&eacute;riques, c'est transposer le code des signaux, sans modifier les informations qu'ils renferment. Ce qui veut dire, bien &eacute;videmment, qu'un signal ayant subi deux conversions inverses successives retrouvera exactement sa forme initiale. </font> </p>

<p> <font face="Arial" size="3" color="#000000"> La conversion analogique / num&eacute;rique (A / N) encore appel&eacute;e P.C.M. (Pulses Codes Modulation) ou en fran�ais M.I.C. (Modulation par Impulsions Cod&eacute;s) est illustr&eacute;e figure 5. </font></p>

<p align="center"> <img border="0" src="images/Conversion AN_NA.gif" alt="Conversion AN_NA.gif" width="668" height="930"> </p>

<p> <font face="Arial" size="3" color="#000000"> L'onde analogique (a), est &eacute;chantillonn&eacute;e (b), c'est-&agrave;-dire mesur&eacute;e &agrave; intervalles r&eacute;guliers suffisamment rapproch&eacute;s. La fr&eacute;quence d'&eacute;chantillonnage est tr&egrave;s grande par rapport &agrave; celle du signal analogique et particuli&egrave;rement par rapport &agrave; la composante de fr&eacute;quence la plus &eacute;lev&eacute;e dans le cas de signaux composites. </font> </p>

<p> <font face="Arial" size="3" color="#000000"> <A HREF="#retour_1" NAME="note_1"> <b> (2) </b></A> <i> Nous sommes ici dans la zone de texte de la note simul&eacute;e dans une page HTML. </i> </font> </p> <br> <br> <br> <br>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Dans cet exemple, on a très fortement augmenté la taille du browser car avec un texte très court, et, sans schéma ou une image quelconque, on aurait pas pu voir le bon fonctionnement des ancres, de cette façon, on peut tester l'effet recherché.

Les différentes ressources pointées par un lien :

L'extrémité d'un lien peut être n'importe quel type de document :

  • un fichier HTML.

On distingue deux cas, lorsque l'on définit un pointeur vers une URL externe :

  • Le document pointé appartient à un ensemble de documents homogènes dont on a la maîtrise. Dans ce cas, on pourra prévoir, dans le document pointé, une ancre de retour facilitant la navigation dans cet ensemble de documents. Des images représentant un bonton avec une flèche vers la gauche sont souvent utilisées comme pointeur de retour.

Il faut cependant être prudent lorsque l'on décide de gérer ainsi sa propre navigation ; on ne pourra plus utiliser le document dans un autre contexte, sous peine de proposer des choix de navigation qui égareront les Internautes.

Dans la figure 3 ci-dessus, on trouve deux ensembles distincts de documents, l'un nommé Alpha et l'autre nommé Bêta. Dans le document 2 de l'ensemble Alpha, a été posé un lien vers le document B de l'ensemble Bêta. L'Internaute partit de la page Menu de l'ensemble Alpha trouve à la page 2, un lien qui l'emmène vers le document B de l'ensemble Bêta. S'il utilise depuis cette page le bouton [image], il reviendra vers le Sommaire des documents Bêta et non vers le Menu des documents Alpha comme il pouvait l'espérer !

  • Le document pointé se situe sur un serveur ou une zone de serveur indépendant du document en cours de réalisation ; après avoir cliqué sur le lien, l'Internaute reviendra au document de départ à l'aide du bouton back proposé par le browser.

JavaScript et les liens :

Avec JavaScript, les liens d'une page HTML deviennent des objets que l'on peut manipuler. Les objets liens sont relativement simples : trois événements y sont associés, aucune méthode particulière ne s'y applique et la seule propriété qui peut être manipulée est la propriété target qui permet de spécifier la fenêtre, ou la frame dans laquelle s'affiche un document que l'on verra plus tard dans nos études.

Si le lien devient un objet au sens de JavaScript, il est stocké au niveau du document dans un tableau, et on peut ainsi le référencer. Le mot clé pour accéder à un lien est links. Ainsi, dans la nomenclature des objets JavaScript, document.links[0] référence le premier lien décrit dans la page, document.links[1], le second, etc. ...

Comme tout tableau, il est possible de connaître le nombre d'éléments qui le composent (donc le nombre de liens dans la page) par document.links.length. On verra le JavaScript un peu plus tard ainsi que le PHP, au cours de nos leçons ...

Les événements associés aux liens :

Revenons sur le principe de la programmation événementielle : lorsque le concepteur de la page HTML décrit un lien (<A HREF= . . . </A>), il peut souhaiter au moment où l'Internaute fait glisser d'un mouvement de souris le curseur sur cette ancre hypertexte, que quelque chose d'exceptionnel survienne. Dans l'exemple suivant, une puce ou un rectangle de couleur rouge apparaît lorsque le curseur entre sur le lien et disparaît lorsqu'il en sort.

Le concepteur de la page doit donc positionner sur la balise l'événement qu'il veut intercepter et décrire son traitement. Dans la balise HTML, on dispose de nouveaux attributs, les événements auxquels sont associés comme valeur le nom de la fonction JavaScript avec d'éventuels paramètres.

<A HREF= . . . evenement:fonction(parametre1,parametre2 . . .)> texte de l'ancre </A>

Si la fonction n'a pas de paramètres, les parenthèses sont cependant obligatoires.

  • L'événement onMouseOver apparaît lorsque le curseur arrive sur la zone du lien hypertexte.

  • L'événement onMouseOut apparaît lorsque le curseur quitte la zone du lien hypertexte.

  • L'événement onClick apparaît lorsqu'on clique sur le lien.

Exemple d'utilisation des événements onMouseOver et onMouseOut :

Dans l'exemple suivant, on voit comment sont positionnés les événements permettant d'intercepter l'entrée (onMouseOver) ou la sortie (onMouseOut) du curseur sur le lien. On utilise une même fonction (survol) pour traiter cet événement. Si le curseur entre sur le lien, on passera en paramètre la valeur "entree", s'il quitte le lien, on passera en paramètre la valeur "sortie". Le traitement ne fait ensuite que changer la ressource d'une image. Ce traitement sera abordé dans Réalisation d'une carte cliquable animée, que l'on verra au cours de nos études.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> &Eacute;v&eacute;nement sur les liens </TITLE>

<Script>

pointBlanc = new Image();

pointRouge = new Image();

pointBlanc.src ="images/PointBlanc.GIF"

pointRouge.src ="images/PointRouge.GIF"

function survol(lien) {

switch (lien) {

case "entree" :

document.images[0].src=pointRouge.src;

break;

case "sortie" :

document.images[0].src=pointBlanc.src;

break;

}

}

</Script>

</HEAD>

<BODY bgColor="white">

<img src="images/PointBlanc.GIF"> <b> <font face="Arial" size="3" color="#000000">

<A HREF="http://www.electronique-et-informatique.fr/" onMouseOver=survol("entree") onMouseOut=survol("sortie")>

Voulez-vous cliquer ici ? </A> </b> </font> </p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Un rectangle rouge apparaît lorsque la souris survol le lien.

Exemple d'utilisation de onClick :

Dans cet exemple, nous allons définir un lien vers une image, mais celle-ci sera affichée dans une nouvelle fenêtre du browser.

On verra par la suite dans nos études la suite de JavaScript open pour l'ouverture d'une fenêtre.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> onClick sur un lien </TITLE>

<Script>

function creerFenetreImage() {

RefImage = window.open ("","fenetreImage",

"width=640, height=480, scrollbars=no, toolbar=no, location=no, directories=no, status=no");

}

</Script>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000">

<A HREF="images/Ville_Russie.jpg" target="fenetreImage" onClick="creerFenetreImage()">

<b> Visiter la ville de la Russie </b></A></font></p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Cet exemple a pour but de montrer une utilisation de l'événement onClick sur un lien. Le fonctionnement est le suivant : lorsque l'on clique sur le lien "Visiter la ville de la Russie", on exécute d'abord la fonction "creerFenetreImage" qui crée une nouvelle fenêtre du browser, dont le nom sera "fenetreImage". Cette fenêtre a une largeur de 640 pixels sur une hauteur de 480 pixels (width=640, height=480) ; elle est dépourvue du décor habituel de la fenêtre d'un browser : pas d'affichage des boutons, de l'adresse de l'URL en cours ni de la zone de status (toolbar, location, directories, status).

Lorsque cette fenêtre est créée, le lien demandé (Ville_Russie.jpg) est chargé dans la fenêtre spécifiée ("fenetreImage") par l'attribut target.

Exemple de lecture et modification de la destination d'un lien (target) :

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Changement et lecture du target </TITLE>

<Script>

function bidouille() {

document.links[2].target = "fenetreImage";

}

function vite() {

document.links[2].target = "";

}

function creerFenetreImage() {

if (document.links[2].target = "fenetreImage") {

RefImage = window.open ("","fenetreImage"),

"width=640, height=480, toolbar=no, location=no, directories=no, status=no");

}

}

</Script>

</HEAD>

<BODY>

<p><font face="Arial" size="3" color="#000000"> O&ugrave; voulez-vous mettre l'image,

<A HREF="images/Ville_Russie.jpg" title="Fonction TARGET" target="fenetreImage">

dans une nouvelle fen&ecirc;tre</A> ? ou dans

<A HREF="images/Vacances.JPG" title="Fonction sans TARGET">

celle-ci</A> ? <p>

<A HREF="images/Ma_Louloute.jpg" title="Fonction onClick" onClick="creerFenetreImage()">

Voir l'image</A> </p> </font></p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

L'exemple fonctionne de la manière suivante : lorsqu'on clique sur "dans une nouvelle fenêtre", on effectue la fonction images/Ville_Russie.jpg "bidouille". Celle-ci ouvre une nouvelle fenêtre pour le lien numéro 2 (Ville_Russie.jpg), une destination de l'affichage (un target) égale à "fenetreImage". Si l'on clique sur "celle-ci", on effectue la fonction images/Vacances.JPG "vite" qui affecte une chaîne nulle au lien numéro 2 ; la chaîne nulle indique que l'on ne change pas la destination d'affichage. Maintenant, si l'on clique sur "voir l'image", on effectue la fonction "creerFenetreImage" ; cette fonction teste le target du lien numéro 2, et si celui-ci est égal à "fenetreImage", la fenêtre correspondante est créée, permettant à l'image de s'afficher dans cette nouvelle fenêtre. Si, en revanche, le résultat du test est nul, il n'y a pas de création de fenêtre et l'image s'affiche de façon standard, dans la fenêtre d'origine ainsi le document initial.

Ne vous inquiétez pas si vous ne comprenez pas ce principe, on reviendra plus tard sur les fonctions au cours de nos études. Pour l'instant, admettez la théorie.

Nous résumons cette sixième leçon ci-après :

Nous avons appris que la balise <A> permet de décrire les liens hypertexte dans un document. On distingue :

  • Les liens définissant un accès vers un document. L'attribut utilisé dans ce cas est HREF, qui permet de définir l'adresse du document ou d'une page HTML à atteindre. Cette adresse peut être :

Une URL standard : <A HREF="URL"> . . .</A>

Une étiquette vers un point précis du document : <A HREF="#LABEL">. . .</A>

La combinaison des deux seront : <A HREF="URL#LABEL">. . .</A>

Le texte situé entre les balises <A> et </A> s'appelle l'ancre ; il sera mis en évidence par le browser car, c'est une zone cliquable (soulignement, couleur, etc.).

  • Les liens définissant un point d'entrée dans un document. L'attribut utilisé ici est NAME, qui définit un label (une sous-adresse) dans le document : <A NAME="LABEL">. . .</A>

Le texte situé entre les balises <A> et </A> n'a aucun attribut visuel, ce n'est pas une zone cliquable.

L'extrémité d'un lien peut être : un fichier HTML, une image, un film ou un texte.

Il est possible de décrire des liens vers d'autres services de l'Internet comme : FTP, NEWS, MAILTO, TELNET, JAVASCRIPT, etc.

Dans un contexte JavaScript, chaque lien est rangé dans un tableau et on peut accéder à un lien par son indice : document.links[indice]

Le nombre de liens d'une page HTML peut être connu par la valeur document.links.length.

La seule propriété d'un lien pouvant être lue ou modifiée est document.links[i].target.

Enfin, il existe trois événements associés au lien :

  • onMouseOver

  • onMouseOut

  • onClick

Fin de cette sixième leçon, la prochaine sera consacrée aux Inclusions d'images concernant le langage HTML.


Les Inclusions d'Imageries HTML

Les Inclusions d'Imageries HTML :

Cette leçon décrit les méthodes permettant d'inclure des images dans la conception de pages HTML, mais n'aborde pas les procédés destinés à la fabrication ou au traitement d'images. Cet aspect sera abordé plus tard au cours de nos leçons.

Les images en ligne :

On entend par image en ligne, une image dont l'affichage se fait automatiquement dans la fenêtre du browser lors du transfert de la page HTML. Cet affichage est quasi simultané avec l'apparition du texte de la page ; l'illustration trouve sa place dans le document HTML dans les mêmes conditions qu'une photo sur une page imprimée.

Il existe plusieurs façons d'enregistrer une image numérique pour la stocker sur un support informatique. Comme tous les browsers graphiques doivent pouvoir comprendre le format dans lequel a été encodée l'image, le format GIF (Graphics Interchange Format) s'est imposé comme standard. Il s'agit d'un format compressé, conçu pour optimiser les temps de téléchargement et permettant le traitement d'images en couleurs ou en niveaux de gris. Ce format n'autorise pas de donner plus de 256 couleurs à un point de l'image (pixels). D'autres formats comme XBM ou JPEG peuvent être utilisés. Employer le format GIF ou JPEG dans des images en ligne, c'est s'assurer que les Internautes les recevront correctement quel que soit le browser utilisé.

<IMG> :

C'est la balise permettant d'inclure une image. Elle sera toujours complétée par l'attribut SRC, qui permet de donner l'adresse du fichier graphique contenant l'image :

<IMG SRC= "images/repertoire/sous_repertoire/nom_du_fichier_graphique">

Dans l'exemple qui suit, le répertoire images se situe au premier niveau par rapport à la racine du serveur, et l'image cheval.gif se trouve dans le sous-répertoire animaux.

Exemple :

<img src="/images/animaux/cheval.gif">

En toute logique, l'image que l'on propose dans une page HTML d'un serveur devrait toujours résider sur ce serveur.

La valeur de l'attribut SRC permet cependant de spécifier une URL, si bien qu'il est tout à fait correct de trouver des images définies dans une URL comme suit :

<img src="http://www.electronique-et-informatique.fr/images/animaux/cheval.gif">

Ou encore comme ci-après :

<img src="ftp://ftp.electronique-et-informatique.fr/publicite/images/cadeaux/surprises.gif">

L'URL peut être exécutée, par exemple, sur le serveur http://www.business.com, ces lignes provoqueront une connexion au serveur comme ci-après : TOTO, et les images s'afficheront bien ; cet affichage est néanmoins subordonné à la disponibilité du serveur http://www.business.com et à la qualité de la transmission.

Une image peut être aussi insérée au fil du texte, mais si l'on désire affecter un style particulier au texte qui se trouve sur la même ligne que l'image, il faut définir la balise de style avant de définir l'image si la balise est de type <Hn>. En effet, la balise de type <H> provoque un retour à la ligne, l'inverse de l'effet souhaité. Si la balise est une balise de style physique comme <i>, il n'y a pas de règle à respecter.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Les images en ligne </TITLE>

</HEAD>

<BODY>

<H3> Carte m&egrave;re fabriqu&eacute;e <img border="0" src="images/Carte_Mere.gif" width="700" height="516"> <i> en 2005 par Microsoft </i></H3>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Alignement des images :

La balise <IMG> admet un attribut de présentation permettant de situer l'image par rapport à la ligne de texte courante. Il s'agit de l'attribut ALIGN, dont les valeurs peuvent être les suivantes :

  • ALIGN=TOP pour aligner le haut de l'image sur la ligne courante,

  • ALIGN=MIDDLE pour aligner le milieu de l'image sur la ligne courante,

  • ALIGN=BOTTOM pour aligner le bas de l'image sur la ligne courante.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Les images en ligne : Alignement </TITLE>

</HEAD>

<BODY>

<H2> Voici <img border="0" src="images/Enfant_3.jpg" width="100" height="100" align="texttop"> quatre images <img border="0" src="images/Enfant_4.jpg" width="100" height="100" align="middle"> align&eacute;es <img border="0" src="images/Enfant_7.jpg" align="bottom"> diff&eacute;remment. <img border="0" src="images/Enfant_6.jpg" width="100" height="100" align="absmiddle"> </H2>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

D'autres attributs, LETF et RIGHT permettent au texte de couler autour de l'image, avec un réglage de l'espace vertical VSPACE et un réglage de l'espace horizontal HSPACE.

Il est aussi possible également de redéfinir la taille de l'image à l'aide des attributs WIDTH (largeur) et HEIGHT (hauteur), mais il faut savoir que, d'agrandir ou diminuer une image peut nuire à sa qualité de cette dernière.

Ces deux attributs qu'on vient d'évoquer sont aussi très intéressants, pour obtenir, à partir d'un seul pixel coloré, des rectangles de différentes largeur et hauteur. On peut ainsi calculer et réaliser des histogrammes, en utilisant une image constituée d'un seul pixel que l'on redimensionne !

Enfin, il est possible d'affecter l'image d'un cadre noir avec l'attribut BORDER. Pour tous ces attributs, la valeur s'exprime en points.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Les images en ligne </TITLE>

</HEAD>

<BODY>

<H2> Image Originale </H2>

<img src="images/Daniel.jpg">

<H3> Image r&eacute;duite, align&eacute;e et encadr&eacute;e &agrave; l'aide d'extensions de certains navigateurs </H3>

<img src="images/Daniel.jpg" align="right" hspace="20" vspace="30" width="350" height="300" border="8" >

<p> <font face="Arial" size="3" color="#000000"> Nous mettons quelques phrases de nos le&ccedil;ons d'&eacute;lectroniques afin de pouvoir d&eacute;montrer l'exemple comme ci-apr&egrave;s : </font> </p>

<p> <font face="Arial" size="3" color="#000000"> Tout au long de ce d&eacute;veloppement, on aura souvent recours &agrave; des figures pour repr&eacute;senter d'une fa&ccedil;on analogique les ph&eacute;nom&egrave;nes qui se produisent dans les semi-conducteurs. Le recours &agrave; ces figures est utile toutes les fois qu'il n'est pas possible de visualiser directement le ph&eacute;nom&grave;ne &agrave; &eamp;acute;tudier. M&ecirc;me si cette repr&eacute;sentation est toujours approximative et ne reproduit pas fid&egrave;lement le ph&eacute;nom&egrave;ne, elle peut toutefois, d'une certaine fa&ccedil;on et pour un temps donn&eacute;, repr&eacute;senter du mieux possible les ph&eacute;nom&egrave;nes connus. </font> </p>

<p> <font face="Arial" size="3" color="#000000"> Le courant parcourant ce circuit est toujours dirig&eacute;, selon le sens conventionnel, du p&ocirc;le positif au p&ocirc;le n&eacute;gatif de la pile : il entre dans la r&eacute;sistance par l'extr&eacute;mit&eacute; rep&eacute;r&eacute;e &agrave; l'aide de la lettre A et sort par celle rep&eacute;r&eacute;e &agrave; l'aide de lettre B. Dans un tel circuit, la tension engendrant le courant continu est appel&eacute; tension continue. Il existe par contre d'autres types de g&eacute;n&eacute;rateurs, lesquels d&eacute;livrent un courant, qui, par ses caract&eacute;ristiques est appel&eacute; courant alternatif. Pour comprendre la diff&eacute;rence entre ces deux types de courant, il est n&eacute;cessaire tout d'abord de se r&eacute;f&eacute;rer &agrave; la figure 1-b. Celle-ci repr&eacute;sente le m&ecirc;me circuit &eacute;lectrique que la figure 1-a, &agrave; la diff&eacute;rence pr&egrave;s qu'il est aliment&eacute; par un g&eacute;n&eacute;rateur de courant alternatif dont nous pouvons noter au passage le symbole graphique. Dans cette figure 1-b, les polarit&eacute;s du g&eacute;n&eacute;rateur de courant alternatif, indiqu&eacute;es par les signes &laquo;+&raquo; et &laquo;-&raquo; sont identiques aux polarit&eacute;s apparaissant dans le circuit de la figure 1-a. En cons&eacute;quence, dans ces deux cas de figure, le courant circule dans le m&ecirc;me sens traversant la r&eacute;sistance de A vers B. Cependant, dans le cas d'un g&eacute;n&eacute;rateur alternatif, le courant ne circule dans un sens que durant un temps tr&egrave;s bref, au bout duquel il s'inverse. Nous sommes alors en pr&eacute;sence de la figure 1-c o&ugrave; les polarit&eacute;s du g&eacute;n&eacute;rateur sont invers&eacute;es et o&ugrave; le courant traverse la r&eacute;sistance de B vers A. M&ecirc;me dans ce nouveau sens de circulation, le courant ne persiste que durant un temps tr&egrave;s bref pour ensuite revenir dans le cas de la figure 1-b et ainsi de suite. Nous pouvons dire que le courant change p&eacute;riodiquement son sens de circulation, autrement dit qu'il parcourt la r&eacute;sistance alternativement de A vers B et de B vers A durant des p&eacute;riodes de temps tr&egrave;s br&egrave;ves. de cette explication, nous comprenons l'origine de l'appellation du courant alternatif. L'intensit&eacute; d'un courant alternatif varie constamment, dans le cas de la figure 1-b elle augmente de z&eacute;ro jusqu'&agrave; une valeur maximale d&eacute;termin&eacute;e par le g&eacute;n&eacute;rateur et la r&eacute;sistance, puis diminue pour revenir &agrave; z&eacute;ro. A l'instant o&ugrave; l'intensit&eacute; est nulle, le g&eacute;n&eacute;rateur inverse ses polarit&eacute;s, nous sommes dans le cas de la figure 1-c, l'intensit&eacute; augmente &agrave; nouveau jusqu'au m&ecirc;me maximum que pr&eacute;c&eacute;demment et redescend ensuite &agrave; z&eacute;ro. A cet instant, il se reproduit un changement de polarit&eacute;s et le cycle recommence.</font> </p>

<p> <font face="Arial" size="3" color="#000000"> Du moment que la r&eacute;sistance est fixe, les variations d'intensit&eacute; du courant I ne peuvent &ecirc;tre dues qu'&agrave; des variations analogues de la tension fournie par le g&eacute;n&eacute;rateur. Cette tension poss&egrave;de les m&ecirc;mes caract&eacute;ristiques que le courant qu'elle fournit et est appel&eacute;e tension alternative.</font> </p>

<br><br><br> <!-- Ici, nous avons mis trois retours volontairement pour laisser plusieurs espace dans le Navigateur -->

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

On peut évidemment justifier les phrases côté droit du browser.

Comme vous eûtes certainement pu vous apercevoir jusqu'à présent, que vous pouvez faire copier / coller, dans votre logiciel favoris ou du bloc note à partir de tous nos exemples sus évoqués.

Nous savons que l'attribut <ALT> accompagné du texte de substitution remplit cette fonction, en cas d'absence d'images par certains browsers :

<IMG SRC="photo.gif" ALT="Photo du cheval">

En cas de non affichage de la photo, l'Internaute trouvera ce texte, qui pourra aider à une meilleure compréhension du document.

Les images en guise d'ancres :

On peut tout à fait remplacer le texte d'une ancre par une balise définissant une image.

<A HREF="Photo.jpg"> <IMG SRC="Photo.mini.gif"> </A>

Dans ce cas, l'image est encadrée par un filet de couleur pour indiquer qu'il s'agit d'un lien hypertexte sur lequel on peut cliquer.

C'est cette méthode qui est utilisée pour placer des boutons de navigation dans les pages HTML.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Les images </TITLE>

</HEAD>

<BODY>

<p> <font face="Arial" size="3" color="#000000"><b>E</b>n cliquant sur l'imagette, vous obtiendrez une vue agrandie du tableau, <i> (format JPEG) </i> </font></p><p>

<a href="images/Tableau.jpg">

<img src="images/Tableau_small.jpg"> </a> <p> <font face="Arial" size="3" color="#000000">

<b>V</b>ous pouvez aussi

<a href="images/Tableau.jpg"> cliquer ici</a> </font> </p> <p><hr><br>

<a href="Page_1.html"> <img src="images/Gauche.png" title="Page pr&eacute;c&eacute;dente"></a>

<a href="Home.html"> <img src="images/Haut.png" title="Sommaire"></a>

<a href="Page_2.html"> <img src="images/Droit.png" title="Page suivante"></a> <h4>

| <a href="Page_1.html"> Page pr&eacute;c&eacute;dente</a>

| <a href="Home.html"> Sommaire</a>

| <a href="Page_2.html"> Page suivante</a> | </h4>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Les images et JavaScript :

On verra par la suite de nos études concernant le JavaScript Image() . . .

Tout comme les liens, les images sont rangées dans un tableau et sont accessibles grâce au mot clé images.

document.images[i] référence les images d'une page HTML avec i variant de 0 à document.images.length-1, document.images.length donnant le nombre d'images contenues dans la page.

L'objet image possède quatre propriétés :

  • SRC définit l'adresse (l'URL) du fichier contenant l'image,

  • HEIGHT retourne la hauteur de l'image en pixels (propriété non modifiable),

  • WIDTH retourne la largeur de l'image (propriété non modifiable),

  • COMPLETE renseigne sur l'état de l'affichage de l'image (à la valeur false (faux) tant que l'image n'est pas complètement affichée, true ensuite "vraie").

Exemple de modification d'image :

Lorsque la souris passe sur le chiffre 1, il est aussitôt remplacé par le chiffre 2 ; le chiffre 1 revient lorsque la souris sort de l'image.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Les images 1 et 2 </TITLE>

<SCRIPT>

un = new Image(); deux = new Image();

un.src = "images/Un.gif"; deux.src = "images/Deux.gif";

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#FFFFFF">

<A HREF=http://www.electronique-et-informatique.fr/Electronique-et-Informatique/index.htm

onMouseOver="document.images[0].src=deux.src"

onMouseOut="document.images[0].src=un.src">

<IMG SRC="images/Un.gif" border="0"> </A>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

On trouvera dans l'exemple de la Réalisation d'une carte cliquable animée, au cours de nos leçons, une autre utilisation de l'objet image.

Et enfin, nous allons résumer cette septième leçon que nous espérâmes utiles dans vos futurs projets.

On peut inclure deux types d'images dans un document HTML :

  • Les images en ligne sont celles qui apparaissent dans la page HTML, elles sont généralement au format GIF ou JPEG ou même voire PNG dans certains cas.

La balise pour inclure une image en ligne est la suivante :

<IMG SRC="URL_DU_FICHIER.GIF">

D'autres attributs sont possibles :

ALT = texte pour spécifier un texte de substitution pour les browsers non graphiques "qui sont rare actuellement" mais, cela peut arriver.

ALIGN = TOP ou BOTTOM ou MIDDLE pour aligner l'image sur une ligne de texte par exemple.

D'autres attributs permettent de redimensionner et de faire flotter une image dans un texte :

ALIGN = LEFT ou RIGHT font flotter l'image soit à gauche, soit à droite du texte.

WIDTH = L et HEIGHT = H, d'où L et H représentent la largeur et la hauteur de l'image en pixels.

BORDER = n, n représente l'épaisseur du trait bordant de l'image ; la valeur 0 supprime la bordure.

  • Les images externes sont des fichiers graphiques pointés par des liens hypertexte :

<A HREF="URL_DU_FICHIER.GIF">ANCRE</A>

<A HREF="URL_DU_FICHIER.JPG">ANCRE</A>

  • Propriétés JavaScript :

Les images sont stockées dans le tableau images. Le nombre d'images du document est : DOCUMENT.IMAGES.LENGTH

SRC : URL DU FICHIER IMAGE.

HEIGHT et WIDTH : donnent les dimensions de l'image.

COMPLETE : Affichage complet (true) ou non (false).

Fin de cette septième leçon, la prochaine sera consacrée à la "Mise en page" concernant le langage HTML.


Les Mises en pages HTML

Les Mises en Pages HTML :

Nous allons décrire dans cette leçon un certain nombre de balises de présentation, en rappelant qu'il appartient à l'auteur d'une page de s'assurer ques ses Internautes auront le browser "convenable" pour visiter ces pages.

Intranet ou Internet ?

Dans le cas de l'édition de pages pour un intranet de société, la tâche de l'auteur est simplifié : si l'ensemble des postes de consultation utilisent le même browser au même niveau, il peut alors créer ces pages, en utilisant toutes les fonctionnalités reconnues par celui-ci.

Dans le cas de création de pages pour l'Internet, il faut plus de prudence, et indiquer sur la première page pour quel browser sont conçues les pages ... Ou accepter que certains lecteurs perdent une partie de l'information !

<FONT> :

Cette balise permet d'agir sur des blocs distincts de caractères pouvant se situer sur une même ligne. Elle permet de régler la taille, la couleur, le type (ou la police) des caractères d'un texte. L'ensemble du texte situé avant la balise de fin </font> est affecté par les attributs de la balise. A l'intérieur de ces balises, on peut imbriquer d'autres balises de style (<B>), <I>, etc.) ou d'autres balises de début <font>.

<FONT SIZE=n COLOR=x FACE=Police_choix1, Police_choix2, Police_choix3>

L'attribut SIZE :

Cet attribut permet de régler la hauteur des caractères à l'aide d'une échelle comprise entre 1 et 7. Si la valeur de l'attribut est précédée du signe +, la valeur indique l'augmentation de taille par rapport aux caractères courants (taille relative). Cette taille par défaut étant de 3, en mesure relative, il ne sert à rien d'incrémenter au-delà du maximum (7, c'est-à-dire +4).

Sans aucun signe, la valeur indiquée est la taille exacte des caractères (valeur absolue).

L'attribut COLOR :

Cet attribut spécifie la couleur des caractères dans le modèle RGB : "rr", "gg", "bb" sont des valeurs hexadécimales comprises entre 00 et FF qui spécifient le degré de saturation des couleurs rouge, vert et bleu dont le mélange produit la couleur souhaitée.

00 représente le minimum et FF le maximum pour une des composantes. Ainsi, la valeur FF0000 donne un rouge avec une intensité maximale, FFFFFF du blanc, 000000 du noir, etc.

L'attribut FACE :

L'auteur d'un document HTML peut choisir la police de caractères utilisée pour le texte à l'aide de cet attribut. Pour que cela fonctionne, il est évident que la police doit résider sur l'ordinateur du poste client. Comme ce n'est pas du tout certain, il est possible de préciser trois choix. Si aucune des polices n'est présente, l'attribut est sans effet, et le texte est affiché avec la police par défaut du browser.

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> Taille et fontes du texte </TITLE>

</HEAD>

<BODY BGCOLOR="#D8D8D8">

Taille courante, <font size="1"> la plus petite taille </font>

et <font size="7"> la plus grande taille </font> <br>

Taille courante, <font size="4"> et taille 4 </font> <br>

Taille courante, <font size="+2"> et taille +2 </font> <br>

<font size="3" color="#0000FF"> <b> <i> Bleu

<font size="+2" color="#FFFFFF"> Blanc

<font size="+3" color="#FF0000"> Rouge </i> </b>

</font>

</font>

</font>

<br>

<font size="+2" color="#FF0000">R

<font color="#00FF00">G

<font color="#0000FF">B </font></font></font> <br>

<font size="7" face="Brush Script MT">

Je suis all&eacute; me promener dans les bois !!! </font>

<font size="7" face="Brush Script MT"> <br> <br>

Texte en Brush Script MT </font>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<MULTICOL> :

Cette balise permet la mise en forme d'un document en colonnes multiples, comme dans un journal : le teste se déroule jusqu'en bas d'une colonne pour continuer dans la colonne suivante. L'ensemble du texte inscrit dans les balises <MULTICOL> et </MULTICOL> est soumis à cet agencement. Cette balise génère un espacement vertical de type paragraphe.

<MULTICOL COLS=n GUTTER=x WIDTH=m>

L'attribut COLS :

C'est attribut spécifie, grâce à sa valeur, le nombre de colonnes de largeur égale sur lesquelles va se distribuer le texte. L'ensemble des colonnes va se répartir en occupant toute la largeur de la page, saut si l'attribut WIDTH vient contrarier cette organisation.

L'attribut WIDTH :

Par la valeur qui lui est affectée, cet attribut optionnel offre la faculté de déterminer la largeur en pixels des colonnes (cette valeur est valable pour l'ensemble des colonnes). Si cet attribut est omis, l'ensemble des colonnes se répartit sur toute la largeur de la page.

L'attribut GUTTER :

La largeur de la gouttière, c'est-à-dire l'espace entre deux colonnes, est caractérisée par la valeur en pixels indiquée à l'aide de cet attribut.

Les balises de début <MULTICOL> et de fin </MULTICOL> fonctionnent plus ou moins bien sur certains navigateurs, c'est pourquoi que nous utiliserons un style prévu à cet effet. Nous devons dire que je ne m'amuserai pas à donner des leçons d'électroniques dans ces conditions, pour s'embêter énormément ...

Exemple d'utilisation, en Style :

<HTML>

<TITLE> Colonnes de texte </TITLE>

<BR>

<BODY BGCOLOR="#FFFFFF"> <font size="+2"> Le&ccedil;ons &Eacute;lectroniques de Base </font>

<BR><BR>

<HEAD>

<STYLE>

#trois_colonnes {

width: 960px;

-webkit-columns: 3 auto;

-moz-columns: 3 auto;

columns: 3 auto;

}

#trois_colonnes p {

margin: 0;

background-color: #E9E9E9;

}

</STYLE>

</HEAD>

<BODY>

<div id="trois_colonnes">

<p> <font size="6">N</font><font face="Arial" size="3" color="#000000">ous mettons volontairement notre texte de nos le&ccedil;ons &Eacute;lectroniques afin que l'exemple puisse fonctionner correctement dans les colonnes correspondantes pr&eacute;vues &agrave; cet effet : </p> <BR>

<p> Le courant I fourni par la pile doit traverser successivement R1 puis R2 pour pouvoir revenir &agrave; la borne "-" de la pile.

Quand deux ou plusieurs &eacute;l&eacute;ments d'un circuit (dans ce cas deux r&eacute;sistances) sont travers&eacute;s successivement par le m&ecirc;me courant, on dit qu'ils sont reli&eacute;s en s&eacute;rie, ou plus simplement qu'ils sont en s&eacute;rie.

Le fait que le courant circulant dans ces &eacute;l&eacute;ments soit le m&ecirc;me pour tous est une caract&eacute;ristique sp&eacute;cifique des liaisons en s&eacute;rie, donc plusieurs r&eacute;sistances en s&eacute;rie sont toutes travers&eacute;es par le m&ecirc;me courant. (Ceci est &eacute;vident et facile &agrave; comprendre).

L'adjonction de la r&eacute;sistance R2 rend la valeur r&eacute;sistive totale du circuit plus grande que s'il n'y avait que la r&eacute;sistance R1, car le courant, outre l'obstacle caus&eacute; par R1 &agrave; son passage, doit &eacute;galement traverser R2. Nous pouvons dire que la r&eacute;sistance totale du circuit de la figure 1 ci-dessus qui s'oppose au passage du courant est donn&eacute;e par la somme des valeurs r&eacute;sistives de chaque r&eacute;sistance. Rappelez-vous que :

La r&eacute;sistance &eacute;quivalente pr&eacute;sent&eacute;e par plusieurs r&eacute;sistances reli&eacute;es en s&eacute;rie s'obtient en additionnant la valeur r&eacute;sistive de chacune des r&eacute;sistances.

Regardons maintenant ce qu'il advient de la tension d&eacute;livr&eacute;e par la pile. Aux bornes de chaque r&eacute;sistance, il appara&icirc;t une tension et ceci conform&eacute;ment &agrave; la loi d'Ohm.

Pour la figure 1, La tension V de la pile se partage entre les deux r&eacute;sistances R1 et R2 pr&eacute;sentes dans le circuit. Aux bornes de R1 appara&icirc;t une tension V1 (d&eacute;termin&eacute;e par les valeurs de I et de R1) et aux bornes de R2 appara&icirc;t une tension V2 (d&eacute;termin&eacute;e par les valeurs de I et de R2). La somme de ces deux tensions est &eacute;gale &agrave; la tension totale de la pile : V1 + V2 = V.

Illustrons par un exemple ce qui vient d'&ecirc;tre affirm&eacute;.

Figure 2 est report&eacute; le m&ecirc;me circuit mais certaines grandeurs &eacute;lectriques sont agr&eacute;ment&eacute;es d'une valeur. </p> </font>

</DIV>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<CENTER> :

Cette balise permet de centrer, dans le sens horizontal de la page, un bloc de texte mais aussi des images ou les éléments d'un formulaire. Elle affecte tous les objets jusqu'à ce qu'apparaisse la balise de fin </CENTER>.

<SPACER> :

La balise <SPACER> permet un contrôle vertical et horizontal du blanc entre des éléments d'une page HTML. On peut ainsi régler de façon précise l'espace entre deux lignes, entre deux mots ou avec d'autres objets comme les images ou les éléments d'un formulaire. Cela permet des réglages plus fins que ceux que l'on pouvait tenter en utilisant la balise <PRE> assortie d'espaces et de retours à la ligne.

<SPACER TYPE=mot_clef SIZE=n> ou <SPACER TYPE="BLOCK" WIDTH=x HEIGHT=y ALIGN=mot_clef>

L'attribut TYPE :

Cet attribut définit, par les valeurs qu'il peut prendre (HORIZONTAL, VERTCAL ou BLOCK), l'espacement entre les objets.

L'attribut SIZE :

Cet attribut à une valeur, en pixels de l'espacement est indiquée par la valeur donnée à cet attribut.

LUNDI<SPACER TYPE=HORIZONTAL SIZE="100">MARDI.

Entraîne l'écriture des mots LUNDI et MARDI avec un blanc inter-mot de 100 pixels tandis que :

LUNDI<SPACER TYPE=VERTICAL SIZE="100">MARDI.

Provoque l'écriture des deux mots sur deux lignes différentes espacées de 100 pixels.

Les attributs WIDTH, HEIGHT et ALIGN :

Si la valeur BLOCK est donnée à l'attribut SIZE, on peut préciser alors ces trois autres attributs. Pour les attributs WIDTH (largeur) et HEIGHT (hauteur), on indique une valeur en pixels ; l'attribut ALIGN ne pourra prendre que la valeur TOP (alignement du sommet du bloc avec les objets qui l'encadrent), BOTTOM (alignement de la base du bloc avec les objets qui l'encadrent également) et CENTER ou MIDDLE (alignement du centre du bloc avec les objets qui l'encadrent).

Le mode BLOCK fonctionne exactement comme l'insertion d'une image, mais à la place de l'image, il n'y a que du blanc ! Nous avouons que nous n'avons pas vraiment trouvé d'utilisation pour ce mode bloc ...

<BR> et l'attribut CLEAR :

L'utilisation de l'attribut CLEAR sur la balise <BR> permet de laisser un blanc d'espace entre une image et le reste de la page. En effet, en l'absence de cette balise, le texte coule naturellement entre l'image et le bord de la page.

Si l'image est positionnée à droite (align=right) pour laisser un blanc d'espace entre elle et le bord gauche de la page, on donnera à l'attribut CLEAR la valeur RIGHT :

<BR CLEAR=RIGHT>

A l'inverse, si l'image est positionnée à gauche :

<BR CLEAR=LEFT>

Ces deux possibilités sont intéressantes dans le cas de texte en colonnes. En effet, si l'on veut glisser une illustration dont la largeur est légèrement inférieure à celle de la colonne, on risque de créer une colonne de texte très étroite dans l'espace restant. L'utilisation de cette balise permet de supprimer cet effet inesthétique.

Si les deux images sont positionnées sur les bords gauche et droit de la page, pour laisser l'espace vide entre elles, on utilisera :

<BR CLEAR=ALL>

Exemple d'utilisation, en Style :

<HTML>

<TITLE> Taille et fontes de texte </TITLE>

<BR>

<BODY BGCOLOR="#FFFFFF"> <font size="+2"> Le&ccedil;ons &Eacute;lectroniques de Base </font>

<BR><BR>

<HEAD>

<STYLE>

#deux_colonnes {

width: 960px;

-webkit-columns: 2 auto;

-moz-columns: 2 auto;

columns: 2 auto;

}

#deux_colonnes p {

margin: 0;

background-color: #E9E9E9;

}

</STYLE>

</HEAD>

<BODY>

<div id="deux_colonnes">

<p> <font size="6">N</font><font face="Arial" size="3" color="#000000">ous mettons volontairement notre texte de nos le&ccedil;ons &Eacute;lectroniques afin que l'exemple puisse fonctionner correctement dans les colonnes correspondantes pr&eacute;vues &agrave; cet effet : </p> <BR>

<img src="images/Enfant_4.jpg" border="0" width="100" height="100" style="float:left; margin-right:10px;"> <p clear="left"> Le courant I fourni par la pile doit traverser successivement R1 puis R2 pour pouvoir revenir &agrave; la borne "-" de la pile.

Quand deux ou plusieurs &eacute;l&eacute;ments d'un circuit (dans ce cas deux r&eacute;sistances) sont travers&eacute;s successivement par le m&ecirc;me courant, on dit qu'ils sont reli&eacute;s en s&eacute;rie, ou plus simplement qu'ils sont en s&eacute;rie.

Le fait que le courant circulant dans ces &eacute;l&eacute;ments soit le m&ecirc;me pour tous est une caract&eacute;ristique sp&eacute;cifique des liaisons en s&eacute;rie, donc plusieurs r&eacute;sistances en s&eacute;rie sont toutes travers&eacute;es par le m&ecirc;me courant. (Ceci est &eacute;vident et facile &agrave; comprendre).

L'adjonction de la r&eacute;sistance R2 rend la valeur r&eacute;sistive totale du circuit plus grande que s'il n'y avait que la r&eacute;sistance R1, car le courant, outre l'obstacle <img src="images/Ma_Louloute.jpg" border="0" width="220" height="360" style="float:left; margin-right:15px;"><p clear="left"> caus&eacute; par R1 &agrave; son passage, doit &eacute;galement traverser R2. Nous pouvons dire que la r&eacute;sistance totale du circuit de la figure 1 ci-dessus qui s'oppose au passage du courant est donn&eacute;e par la somme des valeurs r&eacute;sistives de chaque r&eacute;sistance. Rappelez-vous que :

La r&eacute;sistance &eacute;quivalente pr&eacute;sent&eacute;e par plusieurs r&eacute;sistances reli&eacute;es en s&eacute;rie s'obtient en additionnant la valeur r&eacute;sistive de chacune des r&eacute;sistances.

Regardons maintenant ce qu'il advient de la tension d&eacute;livr&eacute;e par la pile. Aux bornes de chaque r&eacute;sistance, il appara&icirc;t une tension et ceci conform&eacute;ment &agrave; la loi d'Ohm.

Pour la figure 1, La tension V de la pile se partage entre les deux r&eacute;sistances R1 et R2 pr&eacute;sentes dans le circuit. Aux bornes de R1 appara&icirc;t une tension V1 (d&eacute;termin&eacute;e par les valeurs de I et de R1) et aux bornes de R2 appara&icirc;t une tension V2 (d&eacute;termin&eacute;e par les valeurs de I et de R2). La somme de ces deux tensions est &eacute;gale &agrave; la tension totale de la pile : V1 + V2 = V.

Illustrons par un exemple ce qui vient d'&ecirc;tre affirm&eacute;.

Figure 2 est report&eacute; le m&ecirc;me circuit mais certaines grandeurs &eacute;lectriques sont agr&eacute;ment&eacute;es d'une valeur. </p> </font>

</DIV>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

<BODY> pour le décor ! :

Il y a un certain nombre d'attributs de la balise <BODY> permettent de contrôler la couleur de fond de la fenêtre du browser, des caractères du texte et enfin des liens.

L'utilisation de la balise reste inchangée dans la structuration du document HTML :

<HTML>

<HEAD>

<TITLE> Texte de fond d'une page </TITLE>

</HEAD>

<BODY attribut_1 attribut_2 ... attribut_3 attribut_n>

Document

... BLABLA ... BLABLA ...

</BODY>

</HTML>

Les fonds d'écran

L'attribut BGCOLOR :

Cet attribut permet de choisir une couleur pour le fond de n'importe quelle page HTML. Il peut être utilisé sans restriction, car à l'inverse de l'attribut BACKGROUND, il ne consomme pas de bande passante sur le réseau.

Attention à l'abus de ce genre d'artifices, qui peut nuire à la lisibilité de la page et donner un aspect trop clinquant au document.

<BODY BGCOLOR="#rrggbb">

<BODY BGCOLOR="#FFFFFF">

On obtient ainsi une page HTML sur fond blanc, alors que par défaut le fond de la page est gris sur certains browsers.

L'attribut BACKGROUND :

Cet attribut permet de spécifier non plus une couleur mais une image ; celle-ci résidant sur le serveur, on augmente le temps de chargement de la page vers le browser

Le choix de l'image est très important : la texture de l'image devrait être simple et relativement monochrome pour préserver la ligibilité de la page ; en outre, plus sa taille (en octets) sera faible, plus rapide sera son chargement des pages HTML.

<BODY BACKGROUND="fichier_graphique.gif">

fichier_graphique.gif représente l'URL de l'image qui se trouve sur le serveur

Exemple : <BODY BACKGROUND="Decore.gif">

La couleur du texte ci-après :

L'attribut TEXT :

Cet attribut permet de contrôler la couleur du texte standard, c'est-à-dire tout texte ne spécifiant pas un lien. Cet attribut permet d'agir sur l'ensemble du document contrairement à ce qui peut être fait sélectivement par la balise <FONT> et son attribut COLOR. Le codage de la couleur se fait de la même façon que pour l'attribut BGCOLOR.

Exemple : <BODY TEXT="#rrggbb">

Les attributs LINK, VLINK et ALINK :

Ces trois attributs permettent de contrôler la couleur des liens (soit du texte, soit du cadre autour d'une image utilisée en guise de lien).

  • LINK est la couleur d'un lien qui n'a pas encore été visité (bleu par défaut).

  • ALINK est la couleur très fugitive qui apparaît au moment où l'on clique sur un lien (rouge par défaut).

  • VLINK est la couleur d'un lien qui a déjà été visité (voilet-pourpre par défaut).

Exemple d'utilisation :

<HTML>

<HEAD>

<TITLE> R&eacute;glage des couleurs de la page </TITLE>

</HEAD>

<BODY BGCOLOR="#000000" text="#0000FF" link="#FF0000" alink="#FFFF00" vlink="#00FF00">

<H2>

<A HREF="http://www.electronique-et-informatique.fr/Electronique-et-Informatique/index.php">Site Electronique</A> <BR><BR>

<A HREF="http://www.electronique-et-informatique.fr/">Site de Daniel</A> <BR><BR>

<A HREF="http://www.electronique-et-informatique.fr/Forum/lightforum/index.php">Forum de Daniel</A> <BR><BR>

Texte de visualisation pour les couleurs

</H2>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici.

Dans cet exemple, le texte de visualisation pour la couleur standard apparaîtra en bleu, les liens non visités en rouge, le lien au moment du clic en jaune, et le lien déjé visité en vert, le tout sur fond noir.

Nous résumons cette leçon ci-après :

  • Réglage des caractères <FONT> </FONT>

Avec l'attribut SIZE=n, on définit une taille entre 1 et 7.

Avec l'attribut SIZE=+n, on définit la taille par rapport à la taille courante, à savoir 3.

Avec l'attribut COLOR="#rrggbb" pour donner une couleur.

Avec l'attribut FACE=Police 1, Police 2, Police 3, on permet de choisir la police du texte, pour peu qu'au moins une des trois polices spécifiées réside sur l'ordinateur.

  • Colonnage du texte : <MULTICOL> </MULTICOL> (sur certains navigateurs)

L'attribut COLS=n donne le nombre (n) de colonnes du texte.

L'attribut WIDTH=x permet de forcer la taille des colonnes en pixels.

L'attribut GUTTER=x permet de donner la taille de la gouttière en pixels (espace intercolonne).

  • Centrage d'éléments (texte, images, etc.) : <CENTER> </CENTER>

  • Réglage d'éléments (texte, images, etc.) : <SPACER>

L'attribut TYPE permet de préciser si l'on agit horizontalement (horizontal), verticalement (vertical) ou dans les deux sens (BLOCK).

L'attribut SIZE permet de spécifier la quantité de blanc (l'espacement) en pixels pour TYPE=HORIZONTAL ou pour TYPE=VERTICAL.

Les attributs WIDTH=x et HEIGHT=y permettent de spécifier la taille xy en pixels d'un bloc (TYPE=BLOCK).

L'attribut ALIGN prenant une des valeurs TOP, BOTTOM ou CENTER, on peut aligner le bloc (TYPE=BLOCK) par rapport aux objets qui l'entourent.

  • La balise <BR CLEAR=>

CLEAR=RIGHT pour empêcher le texte de couler sur la gauche d'une image située à droite.

CLEAR=LEFT pour empêcher le texte de couler sur la droite d'une image située à gauche.

CLEAR=ALL pour empécher le texte de couler entre deux images, l'une située à droite et l'autre à gauche de la page.

  • Le font de la page :

Avec une couleur de fond : <BODY BGCOLOR="#rrggbb">

Avec une couleur de fond : <BODY BACKGROUND="url_image">

  • La couleur du texte et la couleur des liens.

Couleur de texte : <BODY TEXT="#rrggbb">

Couleur des liens non visités : <BODY LINK="#rrggbb">

Couleur des liens visités : <BODY VLINK="#rrggbb">

Couleur du lien au moment du clic : <BODY ALINK="rrggbb">

Les couleurs sont définies dans le système RGB, chaque composante étant définie sur deux octets dont chacun peut prendre une valeur comprise entre 0 et F (exprimée en hexadécimal).

Exemple de couleurs :

Azur : 74D0F1

Orange : ED7F10

Rose : FD6C9E

Or : D4A017

Gris : 766F6E

Violet : 8D38C9

Lavande : 9683EC

Jaune : FFF000

Pour visualiser l'aperçu, en cliquant ici.

Fin de cette huitième leçon, la prochaine sera consacrée aux "feuilles de Style", concernant le langage HTML.


Les Feuilles de Styles HTML

L'apprentissage des styles tel que nous allons le décrire n'a pas l'ambition d'être complet. Nous avons préféré décrire un sous-ensemble qui fonctionne correctement avec Communicator Netscape ou Internet Explorer et sur certains d'autres browsers, plutôt que de décrire toutes les fonctionnalités présentes dans la norme CSS (Cascading Style Sheets), fonctionnalités qui ne sont pas encore implémentées dans ces browsers et ne le seront peut-être jamais !

Il faut être prudent, en utilisant les feuilles de Style d'autant que lors de l'installation de leurs browsers, Netscape et Internet Explorer de Microsoft désactivent par défaut l'utilisation des feuilles de style. Ainsi, certains exemples que nous vous montrerons fonctionneront avec Internet Explorer et pas avec Netscape et vice-versa et bien sûr, sur d'autres navigateurs également. Il serait dangereux et difficile de dresser la liste de ce qui fonctionne chez l'un et pas chez l'autre, car on peut espérer que demain tout fonctionnera chez l'un et chez l'autre. Disons tout simplement qu'aujourd'hui qu'Internet Explorer reconnaît la norme CSS et que Netscape devrait supporter CSS et JASS (JavaScript Accessible Styles Sheets).

Encore une fois, il est nécessaire de rappeler que l'auteur des pages HTML doit tester ses pages dans plusieurs environnements, sauf s'il connaît bien la configuration utilisée par ses utilisateurs (cas d'un intranet par exemple).

Le principe de la feuille de style est le même que dans un traitement de texte. On ne se préoccupe que de la structuration du texte lorsqu'on le compose, puis on référence dans ce texte, un ensemble d'instructions qui régiront la typographie à appliquer au texte. Ces instructions peuvent se trouver dans le fichier lui-même, mais sont le plus souvent dans un fichier séparé. Ce fichier, la feuille de style, pourra être référencé par un ensemble de documents HTML, garantissant ainsi une homogénéité typographique et de présentation des pages.

Il existe maintenant deux façons de décrire des feuilles de style. La première répond à la norme CSS qui se borne à un langage déclaratif comme HTML ; la seconde, JASS, est issue du langage JavaScript. Cette seconde méthode est plus orientée pour une manipulation dynamique des propriétés décrivant un style. Les deux méthodes font intervenir la notion de mise en cascade qui permet d'imbriquer dans un même document plusieurs styles avec un niveau de priorité. Ainsi, un style défini dans une page HTML sera généralement plus prioritaire qu'un style défini dans un fichier externe. A terme, les Internautes pourront même définir ses propres styles : ils pourront lire son journal en choisissant la taille, la police, la couleur des caractères ...

Comment définit-on un style ? Nous avons vu qu'un nouveau paragraphe était défini à l'aide de la balise <P>. Appliquer un style à un paragraphe, c'est définir un ensemble de caractéristiques pour ce paragraphe. Ces définitions s'appliquent ensuite automatiquement chaque fois qu'une balise <P> est rencontrée

<STYLE> :

Cette balise définit une zone dans la région d'en-tête (<HEAD>) du document HTML où on trouve toutes les définitions de style du document. Comme ces définitions peuvent être décrites en langage CSS ou en JavaScript, on aura recours à l'attribut TYPE pour indiquer le mode de description utilisé.

L'attribut TYPE :

Cet attribut de la balise <STYLE> peut prendre les valeurs suivantes :

  • text/css pour une description à la norme CSS,

  • text/javascript pour une description en langage JavaScript.

<HTML>

<HEAD>

<TITLE> Style </TITLE>

<STYLE TYPE="text/css"> ou <STYLE TYPE="text/javascript">

</STYLE> </STYLE>

</HEAD>

</HTML>

Examinons maintenant à travers d'un exemple simple, comment définir un "Style interne" de paragraphe où la couleur du texte serait bleue et où la taille des caractères serait de 18 points.

<HTML>

<HEAD>

<TITLE> Style Interne </TITLE>

<STYLE TYPE="text/css"> /* Style interne au langage de la m&ecirc;me page HTML, on verra par la suite les Styles externes */

p {font-size: 18pt; color:blue; }

</STYLE>

</HEAD>

<BODY>

<p> Vous voyez sur l'&eacute;cran la page telle qu'elle sera <u>imprim&eacute;e</u>.</p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

N.B. : Ce symbole indique le commentaire /* Commentaire */

P indique que l'on définit un style pour les paragraphes (<P>). Toutes les définitions sont faites entre les accolades { }. On spécifie le mot clé font-size puis, après les deux points (:) la taille de la fonte et sont unité, (pt). Il en va de même pour la couleur. Ne pas oublier le point virgule (;) qui indique la fin d'une instruction après 18pt ainsi que color: blue; ...

Nous allons vous montrer un deuxième exemple pour une feuille de Style Externe que l'on verra les explications un peu plus loin de cette leçon.

<HTML>

<HEAD>

<TITLE> Style Externe </TITLE>

<LINK REL="stylesheet" TYPE="text/css" HREF="Mis_en_Paragraphe_Couleur_Bleue.css">

</HEAD>

<BODY>

<p> Vous voyez sur l'&eacute;cran la page telle qu'elle sera <u>imprim&eacute;e</u>.</p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Vous vous apercevez dans l'aperçu de l'exemple 1 et de l'exemple 2 que les paragraphes sont toujours identiques ainsi que les caractères de police à 18 points, malgré que c'est une feuille de Style externe et que les instructions n'ont pas été insérées dans le langage HTML pour rendre le paragraphe identique de l'exemple 1 mais, nous verrons cela, un peu plus loin au cours de nos leçons.

Classes de Style :

On peut ainsi définir, pour tout élément de structure HTML (<h1> ... <hn>, <blockquote>, <cite>, etc.), un style particulier. Mais, lorsque l'on définit un style pour les paragraphes, il s'applique à tous les paragraphes du document. Afin d'accroître la précision des réglages de typographie, il est possible d'adjoindre autant de classes particulières que nécessaire pour un élément HTML donné, ou de générer des classes s'appliquant à n'importe quelle balise HTML.

Les exemples suivants définissent une classe "rouge" et une classe "noir" qui seront valables pour toutes les balises HTML référençant cette classe, alors que la classe "bleu" ne sera valable que pour la balise <ADDRESS> et la classe grasRouge que pour la balise de paragraphe <P> :

Exemple d'utilisation d'une classe "externe" :

<HTML>

<HEAD>

<TITLE> Style Classe Externe </TITLE>

<LINK REL="stylesheet" TYPE="text/css" HREF="Classe.css">

</HEAD>

<BODY>

<p> Texte de visualisation <span class="vert"> avec une phrase de couleur verte </span> <span class="noir"> alors que cette phrase est de couleur noire. </span> </p>

<p> Texte de visualisation <span class="Address-bleu"> avec une phrase de couleur bleue </span> alors que cette phrase est de couleur noire. </p>

<p> Texte de visualisation <span class="grasRouge"> avec une phrase de couleur grasse rouge </span> alors que cette phrase est de couleur noire. </p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Nous allons vous donner un deuxième exemple de classe mais cette fois-ci, "interne" comme ci-après, ensuite, nous vous expliquerons par une seule image qu'elle sera commentée :

Exemple d'utilisation d'une classe "interne" :

<HTML>

<HEAD>

<TITLE> Style Classe Interne </TITLE>

<STYLE TYPE="text/css">

p {

font-size: 16pt;

color: black;

}

.vert {

font-size: 16pt;

color: green;

}

.noir {

font-size: 16pt;

color: black;

}

.Address-bleu {

font-size: 16pt;

color: blue;

}

.grasRouge {

font-size: 16pt;

color: red;

font-weight: bold;

}

</STYLE>

</HEAD>

<BODY>

<p> Texte de visualisation <span class="vert"> avec une phrase de couleur verte </span> <span class="noir"> alors que cette phrase est de couleur noire. </span> </p>

<p> Texte de visualisation <span class="Address-bleu"> avec une phrase de couleur bleue </span> alors que cette phrase est de couleur noire. </p>

<p> Texte de visualisation <span class="grasRouge"> avec une phrase de couleur grasse rouge </span> alors que cette phrase est de couleur noire. </p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

A noter : Dans le cas d'un site comportant par exemple 5 pages HTML, on peut insérer la syntaxe de la classe interne. En revanche, si vous avez 400 pages HTML, il y a tout intérêt d'insérer le code CSS dans un fichier à part, nommé par exemple Classe.css, cela facilite les mises à jour des paragraphes, couleurs, les mises en forme, etc. ... Il suffira de modifier qu'un seul fichier Externe dans son intitulé Classe.css et les 400 pages se mettront à jour automatiquemet.

Pour rappeler le fichier Style Classe externe CSS, il suffira de mettre le code sur chaque page HTML : <LINK REL="stylesheet" TYPE="text/css" HREF="Classe.css">

Maintenant, nous allons voir une syntaxe JavaScript, je suis contre mais, à titre d'indicatif pour résumer cette leçon :

Exemple d'utilisation en JavaScript :

<HTML>

<HEAD>

<TITLE> Style Externe JS </TITLE>

<SCRIPT LANGUAGE="JavaScript" SRC="Classe.js"> </SCRIPT>

</HEAD>

<BODY>

<!-- Entre ces balises de d&eacute;but et de fin sont vides, ce qui est normal jusqu'&agrave; pr&eacute;sent, puisque le fichier externe JS se trouve &agrave; l'ext&eacute;rieur de ce programme ... -->

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Nous allons détailler le programme Classe.js afin que vous puissiez recopier ce dernier, et pour que vous puissiez également faire des exercices concernant vos travaux d'essais, en n'oubliant pas de cliquer avec le bouton droit de votre souris et pointer sur "afficher code source" lorsque vous visualisez les exemples de nos leçons ...

A noter : Tous nos programmes d'exemples peuvent être recopiés sur un bloc note, il n'est pas nécessaire d'avoir un logiciel HTML ou PHP prévu à cet effet ! Quant au PHP, on expliquera cette programmation assez complexe au fur et à mesure que nous avoncerons dans nos leçons HTML qu'il faut absolument commencer par ce dernier avant d'entre prendre le langage PHP.

Programme "Classe.js" relativement simple ci-après :

str1="<p><br> Texte de visualisation avec une phrase de couleur verte";

document.write("<FONT SIZE=5> <FONT COLOR='green'>" +str1+"</FONT>");

str1="<p>Texte de visualisation avec une phrase de couleur bleue";

document.write("<FONT SIZE=5> <FONT COLOR='blue'>" +str1+"</FONT>");

str1="<p>Texte de visualisation avec une phrase de couleur rouge";

document.write("<FONT SIZE=5> <FONT COLOR='red'>" +str1+"</FONT>");

str1="<p>Texte de visualisation avec une phrase de couleur noire";

document.write("<FONT SIZE=5> <FONT COLOR='black'>" +str1+"</FONT>");

str1="<p><b>Texte de visualisation avec une phrase de couleur graisse choisie rouge fonc&eacute;e</b>";

document.write("<FONT SIZE=5> <FONT COLOR='#800000'>" +str1+"</FONT>");

Comme vous pouvez le constater, le programme est relativement simple, chaque instruction se répète ... Nous devons dire que ce programme n'est pas tellement pratique pour mettre une partie des phrases en couleurs que l'on veut car, on devrait ajouter deux instructions pour mettre un paragraphe en couleur, donc, ce programme n'est guère interressant par rapport au CSS !

En mode CSS, si l'on omet le nom d'une balise HTML et que l'on commence par un point, la définition peut être utilisée avec n'importe quelle balise. En mode JavaScript, le mot clé classes est nécessaire pour définir une classe et le mot clé all permet de spécifier l'ensemble des éléments HTML.

L'attribut CLASS :

Cet attribut permet d'affecter une classe spécifique à une balise HTML ; il recevra donc toujours en paramètre, le nom d'une classe existante.

Remarquons que si la définition des styles connaît deux normes (CSS et JavaScript), l'utilisation des styles est heureusement unique :

Exemple d'utilisation en CSS :

<HTML>

<HEAD>

<TITLE> Style Interne des Paragraphes </TITLE>

<STYLE TYPE="TEXT/CSS">

p {

font-size: 16pt;

color: blue;

}

.grasRouge {

font-size: 16pt;

color: red;

font-weight: bold;

}

.noir {

color: black;

}

</STYLE>

</HEAD>

<BODY>

<BR>

<p class = bleu> Ce texte est bleu ! </p>

<p class = grasRouge> Et celui-ci est rouge et gras ... </p>

<h2 class = noir> Mais celui-ci reste standard car la classe grasRouge ne s'applique qu'au paragraphe ... </h2>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Vous pouvez insérer dans un fichier les codes "CSS externe" ci-dessus qui se trouve en couleur verte, avec un point devant l'extension "CSS" (.CSS) sans oublier le Nom de ce fichier, en essayant de mettre un nom facile à retenir et n'oubliez pas de rappeler votre document avec l'URL ci-après : <LINK REL="stylesheet" TYPE="text/css" HREF="Classe.css"> d'où le nom Classe.css peut être changé à votre guise selon que vous nommâtes concernant votre fichier.

Ainsi, l'exemple précédent fonctionne aussi bien avec une définition de type CSS qu'avec une définition de type JavaScript.

Sous-classe de style (ID)

La définition d'une classe peut être relativement longue si l'on veut régler un grand nombre de paramètres. Imaginons que l'on souhaite deux types de paragraphe dont seule la couleur diffère. On pourrait certes dupliquer la classe et changer uniquement la définition de couleur, mais la duplication de code est toujours une source de problèmes ... Il est donc plus simple de définir un modificateur agissant juste sur le ou les paramètres qui diffèrent.

Exemple d'utilisation en CSS avec #vert comme ID :

<HTML>

<HEAD>

<TITLE> Sous-classe de style avec ID </TITLE>

<STYLE TYPE="TEXT/CSS">

.premiere { color: red; font-size: 20pt; font-weight: bold }

#vert { color: green; font-size: 15pt }

</STYLE>

</HEAD>

<BODY>

<p class = premiere> Texte de visualisation avec une phrase de couleur graisse choisie rouge ... </p>

<p ID = vert> Texte de visualisation avec une phrase standard ... </p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

Le caractère # (dièse) est l'indicateur de définition d'un ID en mode CSS. On peut le faire précéder d'un signe HTML pour restreindre la portée de l'ID à cette balise HTML. Les définitions se font de manière standard, entre accolades :

p#vert { color: green } n'autorise l'ID vert que dans les paragraphes.

L'attribut ID :

Cet attribut peut être utilisé pour réaliser une exception dans une classe ou bien être utilisé seul ; dans ce dernier cas, il ne présente pas de différence fondamentale avec une classe.

Exemple d'utilisation en CSS comme ID :

<HTML>

<HEAD>

<TITLE> Sous-classe de style avec ID </TITLE>

<STYLE TYPE="TEXT/CSS">

.premiere { color: red; font-size: 20pt; font-weight: bold }

p#vert { color: green }

</STYLE>

</HEAD>

<BODY>

<p class = premiere> Ce texte de visualisation et en 20 points, de couleur graisse choisie rouge ... </p>

<p class = premiere ID = vert> Celui-ci en 20 points, gras mais vert ! </p>

<p ID = vert> Ce dernier texte utilise la police par d&eacute;faut, mais sa couleur est verte ... </p>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6].

Nous allons voir maintenant la balise <SPAN>.

<SPAN> avec l'attribut CLASS :

Si l'on veut appliquer les définitions de style d'une classe à autre chose qu'une balise HTML, c'est-à-dire à un bloc de texte non balisé, on dispose de la balise <SPAN>, celle-ci permet de définir un bloc de texte auquel s'appliquera le style référencé avec l'attribut CLASS. Dans l'exemple suivant, on a réalisé un logotype en trois couleurs :

Exemple d'utilisation en CSS avec <SPAN> :

<HTML>

<HEAD>

<TITLE> Les Styles </TITLE>

<STYLE TYPE="TEXT/CSS">

.TITRE { font-Size: 46pt; font-Family: sans-serif; Background-Color: black; }

.INV_TITRE { Background-Color: green }

.BLANC { Color: white }

.ROUGE { Color: red }

.NOIR { Color: black }

</STYLE>

</HEAD>

<BODY>

<SPAN CLASS = TITRE>

<SPAN CLASS = BLANC>&nbsp;&nbsp;HTML <SPAN CLASS = ROUGE>_

<SPAN CLASS = INV_TITRE>_<SPAN CLASS = NOIR>STYLES&nbsp;

</SPAN> </SPAN> </SPAN> </SPAN> </SPAN>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

Nous allons maintenant voir le groupement.

Groupement :

Afin de simplifier l'écriture, il est possible de grouper plusieurs balises HTML sur une même ligne de définition :

Exemple d'utilisation en CSS Groupement :

<HTML>

<HEAD>

<TITLE> Groupements </TITLE>

<STYLE TYPE="TEXT/CSS">

H1, H2, H3, H4 { color: blue; }

</STYLE>

</HEAD>

<BODY>

<H1> Texte de visualisation avec une phrase de couleur bleue "H1" </H1>

<H2> Texte de visualisation avec une phrase standard ... "H2"</H2>

<H3> Texte de visualisation avec une phrase standard ... "H3"</H3>

<H4> Texte de visualisation avec une phrase standard ... "H4"</H4>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

Comme nous l'avions déjà évoqué, vous pouvez insérer le code CSS qui se trouve en couleur verte, dans un fichier séparé ou externe par rapport au langage HTML

Notez qu'une virgule sépare chacune des balises. Il n'y a pas de définition de groupement en JavaScript.

Sélection Contextuelle :

Il est possible de définir dans quel contexte le style va s'appliquer. Dans l'exemple suivant, on souhaite que seules les citations (CITE) définies dans des titres de niveau 3 (H3) soient de couleur bleue :

Exemple d'utilisation en CSS, Sélection Contextuelle :

<HTML>

<HEAD>

<TITLE> S&eacute;lection Contextuelle </TITLE>

<STYLE TYPE="TEXT/CSS">

H3 CITE { color: blue; }

</STYLE>

</HEAD>

<BODY>

<BR>

<H3> Hello, ce texte de visualisation de l'encre noire ["H3"] </H3>

<H3> Hello, toujours en noir ["H3"] </H3> <H3> <CITE> Mais ceci est en Italique de couleur bleu ["H3 CITE"] </CITE> </H3>

<CITE> <H3> Et ce texte de visualisation Italique est en noir ... ["CITE H3"] </H3> </CITE>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

Remarquez bien, qu'à la différence du groupement, il n'y a pas de séparateur entre les balises. En JavaScript, le codage aurait été le suivant :

<STYLE TYPE="TEXT/JAVASCRIPT">

contextual (tags.H3, tags.CITE).COLOR = "blue"

</STYLE>

L'héritage des styles :

Lorsqu'on imbrique d'autres balises à l'intérieur de balises définissant un style, elles héritent du style défini dans les balises de niveau supérieur :

Exemple d'utilisation en CSS de l'héritage des styles :

<HTML>

<HEAD>

<TITLE> H&eacute;ritage des Styles </TITLE>

<STYLE TYPE="TEXT/CSS">

H2 { color: blue }

.vertCactus { color: green; font-size: 25pt }

</STYLE>

</HEAD>

<BODY>

<H2 class> Texte de visualisation avec une phrase de <span class = "vertCactus"> <EM> couleur verte </EM> </span> </H2>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 10].

Les mots « couleur verte » encadrés par la balise EM hérite des définitions faites dans le style vertCactus. Si la classe vertCactus définit une couleure verte, alors les mots « couleur verte » est écrit avec cette couleur.

Définitions dans des fichiers externes :

Le but des feuilles de style est de créer des définitions qui s'appliqueront à un ensemble de pages d'un serveur Web afin d'obtenir un style, une présentation homogène sur toutes les pages. Il serait donc pénible de recopier dans chaque document HTML les mêmes définitions de style.

On va donc décrire dans un fichier spécifique tous les styles, classes, et ID que l'on référencera ensuite dans les documents HTML.

Le fichier de style :

Ce fichier ne contient pas de balise <TYLE>, il ne contient que les définitions dans l'une ou l'autre des syntaxes décrites précédemment et sans aucune référence quant au langage utilisé pour faire ces définitions (CSS ou JavaScript). On peut inclure des commentaires dans un fichier de style. S'il est à la norme CSS, les commentaires sont inclus entre les séquences /* et */ et peuvent comporter une ou plusieurs lignes. En mode JavaScript, la même méthode est reconnue, mais de plus, toute ligne commençant par la séquence // est aussi considérée comme un commentaire. Le nommage du fichier n'a pas de règles ; il n'est pas du tout nécessaire de l'appeler avec une extension de type .htm ou .html.

/* Styles pour les pages de la rubrique "nouvelles" (ces styles doivent être utilisés en mode CSS) */

.premiere { color: red; font-size: 20pt; font-weight: bold }

#vert { color: green; font-size: 15pt } /* Exception */

ou Style pour les pages de la rubrique "nouvelles" // (ces commentaires doivent être utilisés en mode JavaScript)

<LINK> Utilisation des fichiers externes :

Cette balise aura à terme une portée plus grande et permettra de référencer d'autres fichiers externes que les fichiers de style interne. Trois attributs sont nécessaires pour référencer le fichier de style externe :

<LINK REL="STYLESHEET" TYPE="TEXT/NORME" HREF="URL_DU_FICHIER_STYLE">

L'attribut REL="STYLESHEET" :

Il permet d'indiquer que le fichier que l'on veut utiliser est un fichier de style. A l'avenir, la balise <LINK> servira à référencer d'autres types de fichiers.

L'attribut TYPE :

Comme il existe au moins deux normes de définitions des styles et que, dans les fichiers des styles, on ne spécifie pas la norme, c'est pourquoi qu'on va utiliser cet attribut pour l'indiquer :

  • TEXT/CSS

  • TEXT/JAVASCRIPT

L'attribut HREF :

Comme chaque fois qu'il apparaît, cet attribut va pouvoir indiquer par sa valeur l'adresse (l'URL) du fichier externe contenant les styles.

Il existe une seconde façon de référencer un fichier de style externe. Elle s'utilise dans la balise <STYLE> et est similaire à l'appel d'un fichier image (balise <IMG>).

<STYLE TYPE="TEXT/NORME" SRC="URL_DU_FICHIER_DE_STYLE"> </STYLE>

Enfin, il est tout à fait possible de mixer dans un même document HTML des appels à des fichiers externes, qu'ils soient définis en norme CSS ou JavaScript, et des définitions internes.

Les définitions de style :

Nous venons de décrire comment utiliser des feuilles de style dans un document HTML, nous allons maintenant examiner les possibilités offertes pour influencer la présentation du document. Rappelons que chacun des mots-clés s'écrit différemment en CSS ou en JavaScript.

Les polices de caractères :

font-size (fontSize) - taille des caractères.

Permet d'intervenir sur la taille des caractères. On devra lui associer une des valeurs suivantes :

  • En valeur absolue, on peut indiquer soit directement la taille en point, soit une des valeurs suivantes (de la plus petite taille à la plus grande) : xx-small, x-small, smail, medium, large, x-large, xx-large.

  • En valeur relative, on indiquera soit larger pour prendre la fonte directement de la taille au-dessus, soit smaller pour la taille au-dessous. On peut aussi indiquer un pourcentage de la taille courante.

Exemples en mode CSS :

     p {font-size: xx-large}

     p {font-size: 120%}       /*  Augmentation de 120%    */

     p {font-size: 1.2em}      /*  Augmentation de 120%   */

     p {font-size: 24pt}

Exemples en mode JavaScript :

     tags.p.fontSize = "xx-large";

     tags.p.fontSize = "120%";

     tags.p.fontSize = "1.2em";

     tags.p.fontSize = "24";

     tags.p.fontSize = "24pt";

font-syle (fontStyle) :

Une police de caractères est définie soit en normal (droit ou régulier), soit en oblique (oblique ou italique). Les valeurs à associer sont donc : normal ou italic (le mot oblique est aussi reconnu).

font-family (fontFamily) - Famille de caractères :

Par famille de fonte, on entend essentiellement les caractères avec empattement (Times par exemple), sans empattement (comme Helvetica), non proportionnelles (Courier), manuscrites (Kunstler-script) ou fantaisie (Western).

Les valeurs à indiquer seront : serif (police à empattement), sans serif (police sans empattement), cursive (police manuscrite), monospace (police non proportionnelle) et fantasy (police fantaisie) etc. ...

font-weight (fontWeight) - graisse des caractères :

Pour un caractère standard, la valeur à indiquer est normal. Si l'on veut un caractère gras, on indique alors bold, et on peut alors spécifier un niveau de graisse compris entre 100 et 900. Si l'on veut travailler relativement à la graisse des caractères en cours, on peut utiliser bolder (plus gras) ou lighter (plus clair).

Propriétés des textes :

line-height (lineHeight) - Interligne :

L'interligne peut être spécifié directement en point pt ou en pourcentage %. Si l'on ne donne ni l'unité ni le pourcentage, le nombre est interprété comme un multiplicateur. Ainsi, 1.2 ou 1.2em multiplie la valeur par défaut de l'interligne par 1.2 ; en revanche, 20pt donnera un interligne de 20 points. Il faut noter que, d'une manière générale, lorsqu'on travaille en relatif (pourcentage), les définitions incluses héritent de la modification d'interligne.

P {line-height: 20pt }

text-align (textAlign) - Alignement, justification :

Comme dans un traitement de texte, on peut aligner le texte à gauche avec la valeur left, à droite avec right, centrer avec center ou le justifier avec justify.

P { text-align: justify }

text-indent (textIndent) - indentation :

Le retrait du texte sur la première ligne d'un bloc se termine en point, ou en pourcentage, de la même façon que pour l'interligne. On peut appliquer un retrait ou une indentation à la première ligne d'un paragraphe P d'un bloc Hn

P { text-indent: 2em }

text-transform (textTransform) Traitement de la casse :

Cette option est très intéressante lorsque le texte à afficher n'est pas composé, mais plutôt issu d'un traitement automatique, une base de données par exemple. On peut forcer le passage automatique en minuscules par la valeur lowercase, en capitales par la valeur uppercase, ou mettre le premier caractère seulement en majuscules par la valeur capitalize.

H1 { text-transform: capitalize }

Le bloc :

Toute balise provoquant un espace de type paragraphe (<P>, <H1> ...) définit un bloc qui peut être positionné précisément dans une page et dont on peut choisir la couleur ou l'image en fond. Ce positionnement précis permet la conception de document avec une mise en page élaborée, très proche du document papier. Mais attention ! Le positionnement est relatif par rapport au dernier élément inscrit dans la page.

Il est possible de fixer la taille exacte du bloc, en hauteur (height) et en largeur (width) ainsi que la couleur du fond (background-color ou pour JS backgroundColor), ou de disposer une image en fond (background-image) ou pour le JavaScript (backgroundImage).

Les marges peuvent être choisies de façon indépendante :

  • la marge à droire : margin-right (marginRight)

  • la marge à gauche : margin-left (marginLeft)

  • La marge en haut : margin-top (marginTop)

  • la marge en bas : margin-bottom (marginBottom)

On peut aussi régler le blanc autour du bloc :

  • espace à droite : padding-right (paddingRight)

  • espace à gauche : padding-left (paddingLeft)

  • espace en haut : padding-top (paddingTop)

  • espace en bas : padding-bottom (paddingBottom).

La bordure est entièrement paramétrable grâce au mot-clé border-style (borderStyle) ou le paramètre boderStyle permet d'indiquer le style du cadre :

  • avec la valeur none (aucun) pour ne pas afficher de bordure,

  • avec la valeur 3D pour un effet de relief,

  • avec la valeur solid pour un trait plein.

Chacun des traits composant la bordure peut avoir une taille différente :

  • border-top-width (borderTopWidth) pour le segment du haut,

  • border-right-width (borderRightWidth) pour le segment de droite,

  • border-bottom-width (borderBottomWidth) pour le segment de bas,

  • border-left-width (borderLeftWidth) pour le segment de gauche.

La couleur de la bordure est définie par border-color (borderColor).

Nous résumons cette neuxième leçon ci-après :

Les styles d'une page HTML sont définis entre les balises <STYLE> et </STYLE>. L'attribut TYPE de cette balise prendra la valeur text/css ou text/javascript selon que l'on utilisera l'une ou l'autre des deux normes.

Dans la norme CSS (<STYLE TYPE="text/css">), un style se définit par le nom de la balise (P, H1, CITE par exemple) suivi, entre deux accolades { } des définitions afférentes à cette balise. On peut mettre entre accolades autant de définitions que nécessaire en les séparant par un point-virgule (;). Chaque définition est constituée d'un mot-clé (font-size, color par exemple) séparé de sa valeur par deux points (:).

On peut grouper plusieurs balises sur une même définition, il suffit pour cela de séparer les balises par une virgule.

Il est possible d'indiquer que le style ne s'applique à une balise que lorsque celle-ci est incluse dans une autre balise (sélection contextuelle). Pour ce faire, on fait procéder la définition de la liste des balises, mais cette fois, le séparateur n'est pas la virgule mais l'espace.

Dans la norme JavaScript (<STYLE TYPE="text/javascript">), la syntaxe est plus près du nommage objet. On déclare donc pour une balise donnée le mot-clé tags, qui indique que l'on travaille sur une balise. On indique ensuite, derrière un point, la balise (P, H1, CITE par exemple) ; enfin, toujours séparée par un point, la propriété de la balise (fontSize, color par exemple). L'opérateur égale = permet d'affecter une valeur.

En JavaScript, la sélection contextuelle commence par le mot-clé contextual suivi entre parenthèses de la liste des balises. Chaque balise est précédée d'un mot-clé tags et séparée de la précédente par une virgule.

Il existe une notion de classes permettant d'affecter un style à la demande. <P CLASS=laSeule> permet par exemple d'affecter un style particulier (laSeule) ponctuel à la balise <P>.

Une classe est définie par un nom précédé d'un point (.) en mode CSS et par le mot-clef CLASSES en mode JavaScript. Les définitions sont faites comme pour un style de balise.

Afin d'augmenter la souplesse, il existe un niveau supplémentaire de réglage, l'ID. Il permet par exemple de modifier ponctuellement une valeur définie dans une classe.

En mode CSS, un ID est défini par un nom précédé du caractère dièse (#), tandis qu'en mode JavaScript l'ID est défini par le mot-clef ids.

On peut ainsi combiner, dans une même balise, CLASS et ID.

Entre les balises <SPAN CLASS=... ID=...> et </SPAN>, on peut affecter un style à un texte non standard (non balisé).

Il est possible, grâce à l'attribut STYLE, de définir ponctuellement un style pour une balise (<P STYLE="fontSize=50">).

Enfin, la balise <LINK REL="stylesheet" TYPE="text/javascript_ou_css HREF="url_du_fichier"> permet de référencer un fichier externe contenant les styles du document.

Les propriétés permettant d'agir sur les textes sont :

Mode CSS Mode JavaScript Réglage

font-size fontSize taille des caractères

font-style fontStyle normal ou italique

font-family fontFamily empattement, proportionnalité

font-weight fontWeight graisse des caractères

line-height lineHeight interligne

text-align textAlign Alignement, justification

text-indent textIndent décalage première ligne

text-transform textTransform Capitalisation, casse

Toute balise définissant un espace vertical de type paragraphe génère automatiquement un bloc dont on peut contrôler la position :

Mode CSS Mode JavaScript Réglage

margin-right marginRight marge à droite

margin-left marginLeft marge à gauche

margin-top marginTopt marge en haut

margin-bottom marginBottomt marge en bas

padding-right paddingRight blanc à droite

padding-left paddingLeft blanc à gauche

padding-top paddingTop blanc en haut

padding-bottom paddingBottom blanc en bas

Fin de cette neuxième leçon, la prochaine sera consacrée au "Positionnement dynamique", concernant le langage HTML.


Les Positionnements Dynamiques

Les Positionnements Dynamiques HTML :

Jusqu'à présent, au cours de nos leçons, faisons un bilan des différents documents HTML que nous sommes en mesure de produire :

Des pages statiques comportant images et texte ; lorsqu'elles ont été envoyées sur le serveur, elles ont une apparence immuable. Leur mise en page reste relativement limitée.

Des pages que l'on peut qualifier d'interface de saisie, puisqu'elles comportent des éléments d'entrée accessibles au lecteur (les formulaires). Elles peuvent de façon limitée se modifier sans nouvelle connexion au serveur grâce à des scripts (JavaScript). Ces Scripts peuvent agir sur certains éléments existant dans la page, essentiellement les objets du formulaire (listes, champs de saisie, etc.) ou créer de nouvelles fenêtres (alertes, informations, etc.). Ils ne sont pas en mesure d'intervenir sur le texte, ne savent pas réorganiser par exemple un formulaire, en fonction d'un premier choix effectué par le lecteur.

Sous la même dénomination Dynamic HTML, une nouvelle technologie permettant une gestion plus souple du contenu et du comportement de la page. Cette technologie consiste en deux nouveaux concepts simples : les blocs et les couches. Le bloc est intimement lié aux feuilles de style ; il définit un sous-ensemble de la page pouvant contenir texte, images ou formulaire, mais s'enrichit de propriétés particulières : marge à gauche, marge à droite, bordure, couleur, visibilité, etc. Grâce à ces propriétés, il devient possible de placer au pixel près dans une page. Mais surtout les pages deviennent modifiables au travers de script, ce qui autorise le déplacement de blocs, toujours sans recours au serveur, et ainsi la création d'animations. Il est possible à tout moment de rendre un bloc visible, partiellement visible ou invisible. Quant aux couches, elles permettent d'ordonner l'empilement des blocs dans un espace tridimensionnel : premier plan, second plan, arrière plan.

Il est enfin très important de rappeler que HTML n'est dynamique que grâce aux scripts qui seront associés ! On n'animera pas une page si l'on ne décide pas de faire l'effort de programmer un peu ...

Les couches :

On peut imaginer construire plusieurs documents HTML qui s'affichent sur une même page du browser. Chacun des documents est empilé selon un axe Z et peut contenir des blocs de texte, d'images ou de formulaires décrits dans une couche (layer) pouvant être transparente, visible ou invisible. Chacune des couches peut à son tour accueillir d'autres couches, ainsi de suite.

Définir une couche, c'est un minimum lui donner un nom, déterminer sa position dans la page. Si l'on souhaite positionner la couche à une adresse graphique précise dans la page, on utilisera la syntaxe position: absolute et on complétera en donnant au minimum les coordonnées du point en haut et à gauche, LEFT (ou X) et TOP (ou y). La syntaxe position: relative indique que la couche se situera à la suite de la partie du document qui est construit hors de l'ensemble des couches.

Bien sûr, la définition d'une couche peut être faite en mode CSS ou en mode JavaScript.

Mode CSS :

En mode CSS, les caractéristiques de la couche sont codées dans la zone STYLE ; le nom de la couche est précédé du caractère #.

<SPAN> avec Attribut ID :

La construction du contenu de la couche se fait entre les balises <SPAN>, dont l'attribut ID référence une couche précédemment définie ci-dessous dans la zone STYLE.

Exemple d'utilisation du texte :

<HTML>

<HEAD>

<TITLE> Exemple de Couches </TITLE>

<STYLE TYPE="text/css">

#coucheA {position: absolute; left: 140px; top: 130px;}

#coucheB {position: absolute; left: 250px; top: 250px;}

#coucheC {position: relative;}

</STYLE>

</HEAD>

<BODY>

<SPAN ID="coucheA">

<font face="Arial" size="3" color="#800008"> <b> Cette couche absolue se trouve &agrave; 140 pixels &agrave; gauche de votre &eacute;cran et 130 pixels du haut </b> </font>

</SPAN>

<SPAN ID="coucheB">

<font face="Arial" size="3" color="#005500"> <b> Cette couche absolue se trouve &agrave; 250 pixels &agrave; gauche de votre &eacute;cran et 250 pixels du haut </b> </font>

</SPAN>

<SPAN ID="coucheC">

<font face="Arial" size="3" color="#0000FF"> <b> Cette couche est relative donc, elle se trouve en haut </b> </font>

</SPAN>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Nous vous montrons un deuxième exemple ci-dessous :

Exemple d'utilisation texte avec graphiques :

<HTML>

<HEAD>

<TITLE> Exemple de Couches avec Graphiques </TITLE>

<STYLE TYPE="text/css">

#coucheA {position: absolute; left: 120px; top: 200px;}

#coucheB {position: absolute; left: 200px; top: 400px;}

#coucheC {position: relative;}

#DIV1, #DIV2, #DIV3 {border: 1px dashed; padding: 15px; background-color: #CFC; }

</STYLE>

</HEAD>

<BODY>

<SPAN ID="coucheA">

<DIV ID="DIV1">

<font face="Arial" size="3" color="#800008"> <b> Cette couche absolue se trouve &agrave; 120 pixels &agrave; gauche de votre &eacute;cran et 200 pixels du haut [COUCHE "A"] </b> </font>

</DIV>

</SPAN>

<SPAN ID="coucheB">

<DIV ID ="DIV2">

<font face="Arial" size="3" color="#005500"> <b> Cette couche absolue se trouve &agrave; 200 pixels &agrave; gauche de votre &eacute;cran et 400 pixels du haut [COUCHE "B"] </b> </font>

</DIV>

</SPAN>

<SPAN ID="coucheC">

<DIV ID="DIV3">

<font face="Arial" size="3" color="#0000FF"> <b> Cette couche est relative donc, elle se trouve en haut avec une longueur plus grande [COUCHE "C"] </b> </font>

</DIV>

</SPAN>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Mode JavaScript :

Dans ce mode, une seule balise se substitue à la définition de couche en zone STYLE et à la balise <SPAN> :

<LAYER> <ILAYER> :

Les attributs ID, TOP et LEFT :

Cette balise apparaît dans le corps du document. Elle admet l'attribut ID pour nommer la couche ainsi que les attributs de positionnement LEFT et TOP. On utilisera LAYER pour un positionnement absolu dans la page, et ILAYER pour un positionnement relatif au reste du document défini hors couche. Si le document hors couche ne contient absolument rien au moment où l'on utilise ILAYER, le contenu décrit dans cette couche se situe à l'adresse 0,0 (voir figure ci-dessus) du browser (tout en haut à gauche).

Exemple d'utilisation texte avec LAYER et ILAYER :

<HTML>

<HEAD>

<TITLE> Couches LAYER et ILAYER </TITLE>

<STYLE TYPE="text/css">

#coucheA {position: absolute; left: 80px; top: 200px;}

#coucheB {position: absolute; left: 100px; top: 400px;}

#coucheC {position: relative;}

#DIV1, #DIV2, #DIV3 {border: 1px dashed; padding: 15px; background-color: #DADADA; }

</STYLE>

</HEAD>

<BODY>

<LAYER ID="coucheA">

<DIV ID="DIV1">

<font face="Arial" size="3" color="#800008"> <b> Le contenu (LAYER) d&eacute;crit dans cette couche pour un <u>positionnement absolu</u> dans la page se situe &agrave; l'adresse "80,200" du browser [COUCHE "A"] </b> </font>

</DIV>

</LAYER>

<LAYER ID="coucheB">

<DIV ID ="DIV2">

<font face="Arial" size="3" color="#005500"> <b> Le contenu (LAYER) d&eacute;crit dans cette couche pour un <u>positionnement absolu</u> dans la page se situe &agrave; l'adresse "100,400" du browser [COUCHE "B"] </b> </font>

</DIV>

</LAYER>

<ILAYER ID="coucheC">

<DIV ID="DIV3">

<font face="Arial" size="3" color="#0000FF"> <b> Le contenu (ILAYER) d&eacute;crit dans cette couche pour un <u>positionnement relatif</u> se situe &agrave; l'adresse "0,0" du browser [COUCHE "C"] </b> </font>

</DIV>

</ILAYER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

A noter : LAYER signifie COUCHE, ce qui veut dire également qu'on peut parler des CALQUES.

La balise <ILAYER> pour des positions relatives, c'est-à-dire, que le point de départ des coordonnées LEFT et TOP seront prises à l'endroit de la déclaration de la balise <ILAYER>. Son équivalant pour Internet explorer est la balise <DIV>. Vous pouvez utiliser la balise <DIV> avec les ID.

Les attributs Z-INDEX, ABOVE et BELOW :

Normalement, les couches s'empilent du dessous vers le dessus dans l'ordre où elles sont été créées. Il est possible de bouleverser cet ordre à l'aide des attributs suivants :

  • Z-INDEX, auquel on attribue un nombre, permet de classer les couches, en mettant le plus au fond, la couche dont l'index est le plus faible. Ainsi, la couche dont Z-INDEX=2 se trouve au-dessus de la couche dont le Z-INDEX=1.

  • ABOVE (dessus) et BELOW (dessous) fonctionnent différemment ; la valeur qu'ils prennent est le nom d'une couche qui doit déjà exister :

Exemple d'utilisation texte avec Ombrage :

<HTML>

<HEAD>

<TITLE> Couches LAYER avec Ombrage </TITLE>

<STYLE TYPE="text/css">

#coucheA { position: absolute; left: 250px; top: 270px; color: black; font-size: 15pt; }

#coucheB { position: absolute; left: 252px; top: 272px; color: red; font-size: 15pt; }

</STYLE>

</HEAD>

<BODY>

<LAYER ID="coucheA">

<H1> BONJOUR TOUT LE MONDE ! ! ! </H1>

</LAYER>

<LAYER ID="coucheB" ABOVE="coucheA">

<H1> BONJOUR TOUT LE MONDE ! ! ! </H1>

</LAYER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Dans l'exemple ci-dessus, si l'on fait abstraction du paramètre ABOVE, on devrait voir les mots "BONJOUR TOUT LE MONDE ! ! !" écrivent en noir puisqu'on écrit dans chaque couche le mot à la même place (superposition exacte des mots) et que la couleur rouge est définie dans la seconde couche (donc dessous). Or, dans la couche B, on indique grâce à l'attribut ABOVE que la couche A est dessus. Finalement, les mots "BONJOUR TOUT LE MONDE ! ! !" apparaissent en couleur rouge sur certains browsers.

Attention : sur certains navigateurs, l'attribut ABOVE ne fonctionne pas ...

Petite astuce : on peut remarquer dans cet exemple que si l'on décale un peu (1 ou 2 pixels) le texte rouge vers le haut et à gauche, on donne un effet d'ombrage au mot.

Nous verrons au cours de nos exemples, dans les événements JavaScript associés aux couches, que le Z-INDEX permet de réaliser facilement un système de fiches à onglets.

Les attributs BGCOLOR et BACKGROUND :

Ces attributs permettent de contrôler la couleur de la couche ou de mettre une image, en fond de façon tout à fait similaire à la balise <BODY>. Si ces attributs sont absents, la couche est transparente.

Les attributs WIDTH et HEIGHT :

Ils permettent de définir la largeur (WIDTH) et la hauteur (HEIGHT) de la couche. Dans le sens horizontal, il n'y a pas de coupure des mots. En conséquence, si un mot (ou une image) ne tient pas sur la largeur définie, cette largeur est automatiquement étendue. De même, si l'objet ou le texte nécessite une hauteur plus grande que celle qui est définie, cette hauteur est étendue à la taille requise. On peut éviter ces ajustements automatiques à l'aide de l'attribut CLIP.

L'attribut CLIP :

Cet attribut permet de fixer la zone de visibilité de la couche, à l'aide des quatre coordonnées relatives à la couche indiquées dans l'ordre suivant : LEFT (ou X0), TOP (ou Y0), RIGHT (ou X1), BOTTOM (ou Y1). Ainsi, dans la couche définie comme suit, on contraint le contenu de la couche à ne pas dépasser la largeur et la hauteur fixés :

<LAYER ID="SECONDE" LEFT="40" TOP="60" WIDTH="200" HEIGHT="280" CLIP="0, 0, 200, 280">

Toute information hors du champ de visibilité sera perdu ; il n'y a pas de déclenchement d'ascenceurs !

ATTENTION : Les valeurs sont séparées par des virgules. Si l'on ne met pas la chaîne entre guillemets (" "), il ne faut pas mettre d'espaces avant ou après les virgules.

L'attribut VISIBILITY :

C'est en jouant sur la valeur de cet attribut que l'on fait apparaître ou disparaître totalement une couche. Les valeurs peuvent être SHOW pour visible, HIDDEN pour invisible, et INHERIT pour indiquer, dans le cas où des couches sont emboîtées, que la couche hérite de la visibilité de la couche mère.

L'attribut SRC :

Le contenu ou document contenu dans la couche peut être défini comme nous venons de le voir entre les balises <LAYER> et </LAYER>. On peut aussi appeler un document HTML enregistré dans un fichier externe (un peu comme on appelle une image). La valeur attribuée à SRC est l'URL du document à inclure.

Le dynamisme des couches :

Jusqu'à présent, nous avons décrit précédemment, il n'y a pas de comportement dynamique de la page. Tout au plus saurait-on maintenant superposer des textes ou des images. La notion de mouvement, d'apparition ou de disparition d'un élément du décor sera possible car l'ensemble des paramètres de la couche deviendra modifiable, et la page mise à jour en temps réel. Ainsi, on va pouvoir agir depuis un script sur la position du bloc (TOP et LEFT), sur ses dimensions (WIDTH et HEIGHT, sur sa couleur (BGCOLOR), sur sa partie visible (CLIP), sur sa visibilité (VISIBILITY), sur l'empilage (Z-INDEX), etc.

Les propriétés des couches :

1°) - name reflète le nom de la couche spécifiée avec l'attribut ID. Cette propriété n'est pas modifiable.

2°) - left renvoie la position horizontale de la couche par rapport à la couche parente si plusieurs couches sont emboîtées ; s'il n'y a pas d'emboîtement, la position s'effectue par rapport à la page.

3°) - top renvoie la position verticale de la couche par rapport à la couche parente si plusieurs couches sont emboîtées ; s'il n'y a pas d'emboîtement, la position s'effectue par rapport à la page.

4°) - pageX renvoie la position horizontale de la couche par rapport à la page.

5°) - pageY renvoie la position verticale de la couche par rapport à la page.

6°) - zIndex donne la valeur d'empilement affectée à la couche, 0 si aucune affectation n'a été faite.

7°) - bgColor indique la couleur donnée à la couche et null si elle est transparente.

8°) - background.src done l'URL de l'image utilisée en fond.

9°) - clip.top donne la position verticale du début de la zone de visibilité par rapport à la couche. Si l'attribut clip n'a pas été utilisé, la valeur est 0.

10°) - clip.left donne la position horizontale du début de la zone de visibilité par rapport à la couche. Si l'attribut clip n'a pas été utilisé, la valeur est 0.

11°) - clip.right donne la position horizontale de la fin de la zone de visibilité par rapport à la couche. Si l'attribut clip n'a pas été utilisé, on obtient la valeur qui a été affectée automatiquement à la couche.

12°) - clip.bottom donne la position verticale de la fin de la zone de visibilité par rapport à la couche. Si l'attribut clip n'a pas été utilisé, on obtient la valeur qui a été affectée automatiquement à la couche.

13°) - clip.width donne la largeur de la zone de visibilité. Si l'attribut clip n'a pas été utilisé, on obtient la valeur qui a été affectée automatiquement à la couche.

14°) - clip.height donne la hauteur de la zone de visibilité. Si l'attribut clip n'a pas été utilisé, on obtient la valeur qui a été affectée automatiquement à la couche.

15°) - visibility renvoie inherit si la visibilité n'était pas spécifiée ; dans ce cas, il faut aller voir la visibilité du parent pour en déduire si la couche est affichée ou non. Si l'attribut est défini dans la balise, visibility renvoie show ou hide selon le cas.

16°) - src donne l'URL du document dans le cas où le document dans la couche provient d'un fichier externe.

Le nommage des couches dans la hiérarchie JavaScript :

On référence une couche par le mot-clé LAYERS qui s'inscrit dans la hiérarchie des objets JavaScript. Ce mot-clé est indicé par le nom de la couche.

document.layers["nom_de_la_couche"]

document.layers["nom_de_la_couche"].layers["nom_de_la_couche"]

pour des couches imbriquées (couche définie à l'intérieur d'une autre couche).

La hiérarchie des objets dans les couches :

Un document contient une couche qui à son tour contient un document. Ainsi, si un formulaire est défini dans une couche, on accédera à un élément de ce formulaire par :

document.layer["nom_de_la_couche"].document.forms[n].elements[i] ...

On verra l'exemple, un peu plus loin de cette leçon.

Les méthodes des couches :

1°) - moveBy(dx,dy) provoque un déplacement relatif à la position courante.

Exemple : coucheP.moveBy(20,-20) emmène la couche 20 pixels plus à droite et 20 pixels plus haut.

2°) - moveTo(x,y) entraîne le déplacement de la couche à la nouvelle adresse graphique x,y.

3°) - moveToAbsolute(x,y) s'utilise dans le cas des couches emboîtées. En effet, la méthode moveTo provoque alors un déplacement par rapport aux coordonnées de la couche parente. Si l'on veut provoquer un déplacement par rapport à la page du browser, on utilisera cette méthode. Attention : si l'adresse absolue n'est pas à l'intérieur de la couche parente, on perd la couche partiellement ou totalement !

Dans la figure ci-dessus :

1°) - Couche_C.moveToAbsolute(25,25) place la Couche_C au point P ; on perd la visibilité de la Couche_C qui sort de la Couche_P son parent !

2°) - Couche_C.moveTo(25,25) place la Couche_C au point A.

3°) - Couche_C.moveBy(25,25) place la Couche_C au point T.

Le programme suivant permet de tester les différentes options de mouvement.

Exemple d'utilisation de texte LAYER et Mouvement en Escalier :

<HTML>

           <HEAD>

               <TITLE> Couches LAYER avec Mouvements en Escalier</TITLE>

       <STYLE TYPE="text/css">

                #couche_A { position: absolute; left: 120px; top: 120px; color: black; font-size: 18pt; }

                #couche_B { position: absolute; left: 120px; top: 120px; color: blue; font-size: 18pt; }

                #couche_C { position: absolute; left: 120px; top: 120px; color: green; font-size: 18pt; }

                #couche_D { position: absolute; left: 120px; top: 120px; color: yellow; font-size: 18pt; }

                #couche_P { position: absolute; left: 120px; top: 120px; color: brown; font-size: 18pt; }

       </STYLE>

            </HEAD>

          <BODY>

               <BR> <BR>

               <FORM>

               &nbsp;&nbsp;&nbsp;<input type="button" value="Couche A Rouge !" onClick="document.getElementById('couche_A').style.backgroundColor='red'">

               &nbsp;&nbsp;&nbsp;<input type="button" value="Couche B Verte !" onClick="document.getElementById('couche_B').style.backgroundColor='green'">

               &nbsp;&nbsp;&nbsp;<input type="button" value="Couche C Bleue !" onClick="document.getElementById('couche_C').style.backgroundColor='blue'">

               &nbsp;&nbsp;&nbsp;<input type="button" value="Couche D Orange !" onClick="document.getElementById('couche_D').style.backgroundColor='orange'">

               &nbsp;&nbsp;&nbsp;<input type="button" value="Couche P Noire !" onClick="document.getElementById('couche_P').style.backgroundColor='black'">

               &nbsp;&nbsp;&nbsp;<input type="submit" value="Effacement !">

               </FORM>

               <layer id="couche_A">

               <h1> Couche_A </h1>

               <layer id="couche_B">

               <h1> Couche_B </h1>

               <layer id="couche_C">

               <h1> Couche_C </h1>

               <layer id="couche_D">

               <h1> Couche_D </h1>

               <layer id="couche_P">

               <h1> Couche_P </h1>

               </LAYER> </LAYER> </LAYER> </LAYER> </LAYER>

          </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

On peut superposer les couches, voir l'exemple 6 de l'aperçu ci-dessous :

A noter : C'est les mêmes codes que ci-dessus concernant l'exemple 5 donc, on n'indiquera pas les codes CSS et HTML et enfin, vous pouvez néanmoins cliquer sur le bouton droit de votre souris afin d'ouvrir le menu contextuel et pointer sur "afficher code Source", afin de vous rendre compte du programme légèrement modifié.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6].

N.B. : Les exemples 5 et 6 fonctionnent correctement avec les browsers Chrome, Firefox, Opéra sauf sur certains Navigateurs, par exemple, Internet Explorer et autres, qu'on verra par la suite de nos leçons concernant le JavaScript, afin d'apporter des corrections à certains programmes

Nous allons indiquer certains paramètres des couches ci-après, afin de pouvoir insérer dans un programme futur selon nos besoins de chacun de nous tous !!

1°) - resizeBy(dx,dy) augmente ou diminue la taille de la couche selon que dx ou dy sont positifs ou négatifs. Exemple : coucheW.resizeBy(-10,20) diminue la largeur de 10 pixels et augmente la longueur de 20 pixels.

2°) - resizeTo(largeur, hauteur) définit une nouvelle taille absolue pour la couche.

3°) - moveAbove(couche) transfère la couche devant la couche spécifiée en argument. Exemple : coucheM.moveAbove(coucheA) empile la coucheM sur la coucheA.

4°) - moveBelow(couche) transfère la couche derrière la couche spécifiée en argument.

5°) - load(url,largeur) charge dans la couche un nouveau document dont l'URL est spécifiée dans le premier argument. Le second argument est obligatoire et contient la largeur de la couche. Exemple : coucheP.load("/Nanterre/Le_Vesinet_Departemental.html",400).

Les événements liés aux couches :

Ces événements sont au nombre de cinq et sont programmés dans la balise <LAYER>. Mais bien sûr, tout événement programmé sur un autre objet (bouton, lien, ...) peut lancer un Script qui interviendra sur des composants d'une couche :

1°) - onFocus survient lorsqu'on clique dans la surface d'une couche.

2°) - onBlur survient lorsqu'on quitte la surface d'une couche, en cliquant ailleurs.

3°) - onMouseOver survient lorsque le curseur glisse sur la couche, sans qu'il soit nécessaire de cliquer.

4°) - onMouseOut survient lorsque le curseur quitte la couche.

5°) - onLoad survient lorsque la couche est chargée par un fichier externe, que la couche soit en mode visible ou non.

Nous allons maintenant étudier quelques exemples très simples permettant de comprendre comment animer du texte ou des zones de texte standard à l'aide d'événements. La grande originalité est que maintenant, on intervient pas seulement sur des objets de formulaire ou sur des images, mais sur du texte ou sur des ensembles incluant tout ce qu'il est possible de mettre dans un document HTML.

Exemple de déplacement d'un texte :

Examinons un exemple simple animant un texte. Il fonctionne de la façon suivante : lorsque l'Internaute approche le pointeur de la souris sur des boutons ou images à votre guise, le texte défile. Celui-ci s'enfuit en glissant, selon une diagonale vers le bas de l'écran ou vers le haut ou encore, soit à gauche, soit à droite du moniteur selon le sens de la position du pointeur de la souris. Le principe d'une telle animation repose sur l'événement onMouseOver programmé dans la couche contenant le texte. Chaque fois que le pointeur de la souris survole les boutons, une fonction, qui augmente les valeurs TOP et LEFT et déplace le texte, est appelée. On peut remarquer qu'à l'événement onMouseOver sont associées deux instructions JavaScript, ce qui est parfaitement légal. La première instruction initialise deux variables globales (dx et dy), en fonction du déplacement du pointeur de la souris, la seconde instruction appelle la fonction qui va animer le texte (OnMouseOver).

Exemple d'utilisation de texte avec Mouvements de défilement :

<HTML>

           <HEAD>

               <TITLE> Couches avec Mouvements de D&eacute;filement </TITLE>

       <Script language="JavaScript">

                function deplace (dx,dy) {

                document.getElementById('Deplacement_Text').style.top

                = parseInt(document.getElementById('Deplacement_Text').style.top)+dy+'px';

                document.getElementById('Deplacement_Text').style.left

                = parseInt(document.getElementById('Deplacement_Text').style.left)+dx+'px';

                }

        </Script>

            </HEAD>

          <BODY>

           <p> <font face="Arial" size="5" color="#800008"> <b> <center> Effleurer l&eacute;g&egrave;rement les boutons et le texte d&eacute;file ! </b> </center> </font> </p>

               <BR> <BR>

                &nbsp; &nbsp; &nbsp; <input type="button" value="D&eacute;placement Haut ! "OnMouseOver = "deplace (0,-50)">

                &nbsp; &nbsp; &nbsp; <input type="button" value="D&eacute;placement Bas ! "onMouseOver = "deplace (0,50)">

                &nbsp; &nbsp; &nbsp; <input type="button" value="D&eacute;placement Gauche ! "OnMouseOver= "deplace (-90,0)">

                &nbsp; &nbsp; &nbsp; <input type="button" value="D&eacute;placement Droit ! "OnMouseOver= "deplace (90,0)">

                <div id="Deplacement_Text" style="position: absolute; left: 310px; top: 390px">  <H1> <font color="#004500"> Vous n'arriverez jamais &agrave; cliquer sur ce texte ! </font> </H1> </div>

          </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

La fonction "deplace" est programmée ainsi : lorsque l'événement apparaît, les variables globales (dx et dy) seront égale à zéro si le pointeur de la souris reste dans la position initiale, ensuite, on entre dans la fonction "déplace". On incrémente les valeurs (dx et dy et on teste si cette valeur est supérieure aux variables déjà programmées (voir le code ci-dessus). Si tel n'est pas le cas, on incrémente les marges (TOP et LEFT de la variable de 50 à - 90 pixels et de - 50 à 90 pixels, ceci ayant pour effet de déplacer d'autant le texte vers le bas ou vers le haut, ou encore de la gauche vers la droite. On réalise donc ainsi un glissement progressif de 50 à - 90 pixels dans le cas de cet exemple.

Exemple sur l'empilement des couches :

Cet exemple montre comment réaliser un système de fiches à onglets. En cliquant sur l'onglet, la fiche passe au premier plan.

Exemple d'utilisation de Fiches à Onglets :

<HTML>

           <HEAD>

               <TITLE> Fiches &agrave; Onglets </TITLE>

       <STYLE TYPE="text/css">

                * { margin: 0; }

                html { font: 14px / 20px Arial, sans-serif }

                div { opacity: 0.8; position: absolute }

                #div1 { opacity: 0.8; top: 80px; left: 100px; width: 200px; height: 280px; border: 1px dashed #696; padding: 20px; background-color: #99FFFF; }

                #div2 { opacity: 0.8; top: 80px; left: 342px; width: 200px; height: 280px; border: 1px dashed #696; padding: 20px; background-color: #cfc }

                #div3 { opacity: 0.8; top: 80px; left: 584px; width: 200px; height: 280px; border: 1px dashed #900; padding: 20px 20px 20px; background-color: #fdd }

                #div4 { opacity: 0.8; top: 80px; left: 825px; width: 200px; height: 280px; border: 1px dashed #900; padding: 20px 20px 20px; background-color: #FFFF66 }

                #div5 { opacity: 0.8; top: 20px; left: 100px; width: 925px; height: 20px; border: 1px dashed #900; padding: 20px 20px 20px; background-color: #FFDDFF }

                body { background-color:#E6E6E6 ; color:#000000 }

                .onglet {border:solid 1px black ; padding: 7px 7px 7px 13px; margin: 15px 15px 0px 15px }

                a.onglet { background-color:#FFE6CE ; text-decoration: none }

       </STYLE>

            </HEAD>

          <BODY LINK="#800008" ALINK="#00FF00" VLINK="#005500">

           <div id="div1">

            <center> <h1> <a class="onglet" href="Fiche_1.html">Fiche 1</a> </h1> </center>

            <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Ceci est la fiche 1, elle pourrait contenir une image ! </font> </p> <BR> <BR>

            <p align="center"> <img boder="0" src="images/Enfant_4.jpg" width="120" height"120" </p>

            </div>

            <div id="div2">

            <center> <h1> <a class="onglet" href="Fiche_2.html">Fiche 2</a> </h1> </center>

            <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Ceci est la fiche 2, on pourrait mettre un cours &eacute;lectronique ! </font> </p> <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Pour obtenir une inductance &eacute;lev&eacute;e, il faut que le noyau soit ferm&eacute; sur lui-m&ecirc;me de fa&ccedil;on que l'ensemble des lignes d'induction soit contenu dans le noyau. </font> </p>

            </div>

            <div id="div3">

            <center> <h1> <a class="onglet" href="Fiche_3.html">Fiche 3</a> </h1> </center>

            <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Ceci est la fiche 3, on pourrait mettre un cours informatique ! </font> </p> <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Ils permettent de d&eacute;finir la largeur (WIDTH) et la hauteur (HEIGHT) de la couche. </font> </p> <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Dans le sens horizontal, il n'y a pas de coupure des mots. </font> </p>

            </div>

            <div id="div4">

            <center> <h1> <a class="onglet" href="Fiche_4.html">Fiche 4</a> </h1> </center>

            <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Et enfin, ceci est la fiche 4, on pourrait mettre un cours de physique ! </font> </p> <BR>

            <p align="justify"> <font face="Arial" size="3" color="#000000"> Certaines de ces unit&eacute;s vous sont certainement famili&egrave;res telles que le m&egrave;tre ou le kilogramme ; d'autres probablement vous seront inconnues car elles sont utilis&eacute;es ici pour la premi&egrave;re fois. </font> </p>

            </div>

            <div id="div5">

            <h1> <center> Aper&ccedil;u - <a href="Les_Positionnements_Dynamiques.html">retour</a> </h1> </center>

            </div>

          </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

Cette application fonctionne de la manière suivante : on crée quatre premières couches et quatre premiers styles de feuilles de classe superposables aux couches pour constituer les onglets. Ces quatres couches positionnées sans recouvrement seront toujours visibles et nous avons pas mis un événement de type OnFocus que l'on verra plus tard au cours de nos leçons. Ces quatres premières couches, ont les couleurs suivantes : couleur bleue claire, verte claire, rose claire et enfin, couleur jaune claire ; concernant les feuilles de classe, appartiennent aux onglets comme vous le verrez dans l'aperçu de l'exemple 8.

Les quatre couches suivantes, représentant les fiches, sont ajustées sous ces couches d'onglets. On aurait pu programmer cette application de façon moins concise mais plus compréhensible : sur les événements par exemple onFocus, on aurait appelé un script affectant par exemple la valeur 1 sur le z-index de la fiche correspondante et 0 sur les autres.

Il est à noter que l'on ne peut pas intervenir sur les propriétés above et below qui ne sont accessibles qu'en lecture.

Enfin, remarquez bien qu'un style de paragraphe est appliqué sur le contenu de la fiche afin de "décoller" le texte du bord de chaque fiche. En haut de chaque style de fiche également, vous verrez les onglets fiche 1, fiche 2, fiche 3 et fiche 4 que vous pouver cliquer sur ces derniers qui permettront de charger les pages HTML correspondantes aux fiches.

A noter : Pour bien comprendre cette expérience, il suffit de recopier les codes en faisant comme suit : "copier / coller" puis de les enregistrer dans un bloc note sous un nom par exemple "Essai.html", ne pas oublier le point (.) puis HTML, le tout en minuscule.

Nous vous rappelâmes qu'il ne faut pas confondre une feuille de style de type Couches avec une feuille de style de type Classe. Cependant, pour activer les onglets de chaque page HTML, nous mettons à votre disposition les paramètres suivants : <span class="onglet" href="Fiche_1.html">Fiche 1</span>, ce dernier, l'onglet est actif, tandis que le second ne sera pas actif ou inactif : <a class="onglet" href="Fiche_2.html">Fiche 2</a>.

Exemple sur les méthodes :

Cet exemple propose simplement de diminuer ou d'agrandir la taille du texte relativement simple dans cinq feuilles de style de type couche ...

Exemple d'utilisation pour diminuer ou d'augmenter la taille du texte ou chiffres :

<HTML>

           <HEAD>

               <TITLE> Diminuer ou Agrandir la taille du texte </TITLE>

       <STYLE TYPE="text/css">

                * { margin: 0; }

                html { font: 14px / 20px Arial, sans-serif }

                div { opacity: 1; position: absolute }

                #div1 { opacity: 1; top: 250px; left: 410px; width: 18px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                #div2 { opacity: 1; top: 250px; left: 460px; width: 18px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #FF0000; }

                #div3 { opacity: 1; top: 250px; left: 510px; width: 18px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                #div4 { opacity: 1; top: 250px; left: 560px; width: 18px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #FF0000; }

                #div5 { opacity: 1; top: 250px; left: 610px; width: 18px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                body { background-color: #E6E6E6 }

       </STYLE>

                <Script language="JavaScript" type="text/javascript">

                var taille;

                taille = 1;

                function changerTaille(modif) {

                taille = taille + modif; document.getElementsByTagName("body")[0].style.fontSize = taille + "em"; }

                </Script>

            </HEAD>

          <BODY>

          <CENTER> <BR> <BR> <BR>

          <input type="button" value="Diminuer Taille" onClick="changerTaille(-0.1); return false;">

          <input type="button" value="Agrandir Taille" onClick="changerTaille(0.1); return false;">

          </CENTER>

          <DIV id="div1" <font face="Arial"> <h2> 1 </h2> </DIV>

          <DIV id="div2" <font face="Arial"> <h2> 2 </h2> </DIV>

          <DIV id="div3" <font face="Arial"> <h2> 3 </h2> </DIV>

          <DIV id="div4" <font face="Arial"> <h2> 4 </h2> </DIV>

          <DIV id="div5" <font face="Arial"> <h2> 5 </h2> </DIV>

          </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

La feuille de style interne concernant les codes en css (couleur rouge foncée), on peut le mettre dans un fichier séparé du code HTML sous un nom quelconque, à votre guise, par exemple, "essai.css" y compris le Script de couleur verte foncée, par exemple, essai.js.

Et enfin, pour rappeler la feuille de style externe, il suffit de mettre dans la page HTML, le code ci-après : <LINK REL="stylesheet" TYPE="text/css" HREF="essai.css"> ; le nom essai.css est le nom de la feuille de style. Vous pouvez également rappeler le Script comme ci-après : <SCRIPT LANGUAGE="JavaScript" SRC="essai.js"> </SCRIPT> ; le nom "essai.js" est le nom de la feuille de Script, dans cet exemple, "essai.js".

Exemple d'interface utilisant les couches :

En dehors des quelques exemples simples que nous venons de donner, on trouve sur l'Internet de nombreux sites de démonstration de cette technologie. Souvent, on illustre l'intérêt de cette technique avec des jeux ou des animations. La possibilité de jouer sur la visibilité ou sur la disposition d'un ensemble d'objets composant un écran est très intéressante au niveau de l'ergonomie à donner à une interface de saisie. Dans l'exemple suivant, qui décrit une partie de réservation de type TGV, le bouton de réservation du repas n'apparaît que si l'on sélectionne la première classe. L'interface est ainsi allégée, elle s'adapte aux options prises par le lecteur sans pour autant nécessiter une requête vers le serveur.

Exemple d'utilisation pour faire apparaître ou disparaître un bouton quelconque :

<HTML>

           <HEAD>

               <TITLE> Faire Appara&icirc;tre ou dispara&icirc;tre un bouton </TITLE>

       <STYLE TYPE="text/css">

                * { margin: 0; }

                html { font: 14px / 20px Arial, sans-serif }

                div { opacity: 1; position: absolute }

                #div1 { opacity: 1; top: 250px; left: 271px; width: 128px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                #div2 { opacity: 1; top: 250px; left: 431px; width: 128x; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #FF0000; }

                #div3 { opacity: 1; top: 250px; left: 583px; width: 145px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                #div4 { opacity: 1; top: 100px; left: 100px; width: 980px; height: 40px; border: 1px dashed #900; padding: 20px 20px 20px; background-color: #FFDDFF }

                body { background-color: #E6E6E6 }

       </STYLE>

       <BR> <BR> <BR>

                <Script language="JavaScript">

                function OUI() { document.getElementById("Reservation").style.visibility = "visible" }

                function NON() { document.getElementById("Reservation").style.visibility = "hidden" }

                </Script>

            </HEAD>

          <BODY>

          <DIV ID="div4"> <p align="justify"> <font face="Arial" size="4"> Lorsqu'on clique sur le bouton "Premi&egrave;re classe", on fait appara&icirc;tre le bouton "R&eacute;servation repas". Si l'on clique ensuite sur la "Seconde classe", on fait dispara&icirc;tre ce bouton ! </font> </p>

          <form method="post" action="">

          <table>

          <tr> <td>

          <DIV ID="div1"> <input type="radio" name="Repas" value="oui" onClick="OUI();"> Premi&egrave;re Classe </DIV>

          <DIV ID="div2"> <input type="radio" checked name="Repas" value="non" onClick="NON();"> Seconde Classe </DIV>

          </td> </tr>

          <tr ID="Reservation" style="visibility: hidden;">

          <td>

          <DIV ID="div3"> <input type="checkbox"> R&eacute;servation Repas </DIV>

          </td> </tr>

          </table>

          </form>

          </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 10].

Couleurs et unités :

Dans cette leçon, nous avons utilisé les couleurs, en les nommant plutôt qu'en indiquant la valeur des composantes RGB. En effet, depuis HTML, il est possible d'utiliser les couleurs définies dans la palette Windows VGA (Vidéo Graphique Analogique), soit : aqua, black, fuchsia, gray, green, lime, marroon, navy, olive, purple, silver, red, teal, white, yellow.

Sans indication spéciale, les unités sont le pixel (symbol px) ou encore le point (symbole pt). On peut aussi donner des unités relatives à la taille de la fonte en cours. Ainsi, tags.P.marginLeft="2em" provoquera un espace à gauche égal à deux fois la hauteur de l'élément fonte.

Nous résumons cette dixième leçon ci-après :

On définit une couche par son nom et par son positionnement dans la page, adresse graphique du coin en haut et à gauche : TOP et LEFT

En mode CSS, la couche est définie à l'intérieur des balises de style <STYLE> et </STYLE>. Son nom est précédé du caractère #.

La couche peut être positionnée en absolu ABSOLUTE (adressage graphique dans la page) ou en relatif RELATIVE (adresse graphique par rapport au dernier élément défini dans le document hors couche). Le contenu de la couche est codé entre les balises <SPAN ID=nom_de_la_couche> et </SPAN>.

En mode JavaScript, les balises <LAYER> pour positionnement absolu et <ILAYER> pour positionnement relatif permettent à la fois de définir la couche et d'en coder le contenu jusqu'à la balise de fin </LAYER. En plus d'ID, TOP et LEFT, la balise <LAYER> admet les atibuts suivants : (selon les navigateurs).

  • BGCOLOR pour la couleur de font de la couche,

  • BACKGROUND pour mettre une image en fond,

  • WHIDTH et HEIGHT pour régler la largeur et la hauteur de la couche (en pixels),

  • CLIP pour régler la zone de visibilité de la couche (en pixels),

  • VISIBILITY pour faire disparaître la couche (VISIBILITY=HIDDEN), la montrer (VISIBILITY=SHOW), ou dans le cas de couches imbriquées, pour prendre la visibilité de la couche dans laquelle cette couche est elle-même définie (VISIBILITY=INHERIT),

  • SRC pour permettre d'aller chercher à l'URL qu'il définit un fichier contenant le codage du contenu de la couche (SRC=URL).

Propriétés des couches :

  • NAME renvoie le nom de la couche,

  • LEFT et TOP renvoient l'adresse graphique de la couche relativement aux couches parentes en cas d'imbrications de couches.

  • pageX et pageY renvoient toujours l'adresse graphique de la couche dans la page.

  • zIndex renvoie la valeur d'empilement.

  • bgColor renvoie la couleur du fond.

  • BACKGROUND.SRC renvoie l'URL de l'image mise en fond.

  • CLIP.WIDTH et CLIP.HEIGHT renvoient les dimensions de la zone de visibilité de la couche.

  • CLIP.TOP, CLIP.LEFT, CLIP.RIGHT et CLIP.BOTTOM renvoient les adresses graphiques de la zone de visibilité.

  • VISIBILTY renvoie l'information concernant l'affichage de la couche.

  • SRC renvoie l'URL du document contenu dans la couche si cette dernière utilise un fichier externe.

Méthodes des couches :

  • moveBy (dx,dy) déplacement relatif,

  • moveTo (x,y) déplacement absolu par rapport à la couche,

  • moveToAbsolute déplacement absolu par rapport à la page,

  • resizeBy (dx,dy) augmentation ou diminution de la taille de la couche,

  • resizeTo(largeur, hauteur) redéfinition de la taille de la couche,

  • moveAbove(couche) placement de la couche devant la couche définie en argument,

  • moveBelow(couche) placement de la couche derrière la couche définie en argument,

  • load(url,largeur) chargement du document dont l'URL est spécifiée dans la couche dont la largeur est obligatoirement précisée.

Les événements des couches :

  • onFocus apparaît lorsqu'on clique sur la couche.

  • OnBlur apparaît lorsqu'on quitte une couche en cliquant en dehors.

  • onMouseOver apparaît lorsque la souris survole la couche.

  • onMouseOut apparaît lorsque la souris quitte la surface de la couche.

  • onLoad apparaît lorsqu'un fichier est chargé dans une couche.

Fin de cette dixième leçon, la prochaine sera consacrée aux Images cliquables concernant le langage HTML.


Les Images Cliquables HTML

Dans les leçons précédentes, nous avons utilisé des images en guise d'ancre. Nous étions dans une situation où cliquer sur un point quelconque de l'image, entraînait la connexion vers une seule et unique URL (voir les images en guise d'ancres, à cette adresse : En cliquant ici.

A plusieurs reprises, nous avons dit que l'on pouvait associer une URL à une portion d'image, et que, en conséquence, cliquer sur cette zone de l'image pouvait permettre la connexion vers cette URL. La correspondance entre différentes zones d'une image et différentes URL est nommée image cliquable ou encore image réactive.

Cette méthode est tellement utilisée par les concepteurs des sites du serveur WEB qu'on trouve fréquemment des sites où la home-page ne se compose que d'une image cliquable.

Pour réaliser une image cliquable, on commencera par mettre l'image à la taille souhaitée (voir Créer des images au cours de nos leçons futures) que l'on verra par la suite. Si on le peut, on testera la taille de l'image sur diverses dimensions d'écran (PC, Mac, terminaux X), afin de déterminer la taille optimale, en effet, le travail qui va être fait ensuite, est suffisamment fastidieux pour ne pas avoir à le recommencer.

La seconde opération consiste à faire un relevé des coordonnées zone par zone des surfaces cliquables. Si l'on décidait ensuite de modifier la taille de l'image, tout ce travail serait à refaire.

Les zones cliquables vont pouvoir prendre les formes de rectangles, cercles ou polygones.

Système de coordonnées :

Une image se mesure en points (ou pixels) ; l'origine de ces coordonnées se situe en haut et à gauche de l'image.

La première méthode que nous allons décrire, bien qu'un peu ancienne, est encore largement utilisée, et même préférée par certains concepteurs de pages qui lui trouvent l'avantage de fonctionner même avec d'anciennes versions de browsers. Elle présente néanmoins quelques inconvénients : elle nécessite l'installation sur le serveur d'un programme particulier, imagemap, dont le but est de calculer, à partir des coordonnées graphiques l'URL à atteindre. Au niveau de l'utilisation, cette méthode est aussi beaucoup plus lourde puisque cette résolution est à la charge du serveur ; on multiplie les accès réseaux : à chaque clique sur l'image, on fait un aller-retour entre le client et le serveur.

Méthode N° 1 - imagemap, ismap :

Cette méthode est de moins en moins utilisée car, elle nécessite l'exécution d'un programme sur le serveur. On lui préférera la méthode dite usemap, car la résolution complète, coordonnées graphiques et l'URL associée, est réalisée localement par le browser.

Réalisation de la carte coordonnées - URL :

Le premier travail consiste à créer un fichier dont chaque ligne définit une forme géométrique pour la zone cliquable et son URL associée. La syntaxe est la suivante :

Le nombre de points dépend de la forme de la zone :

Le mot clé RECT sera utilisé pour un rectangle défini par 2 points : le sommet en haut à gauche et le sommet en bas à droite.

Le mot clé CIRCLE sera utilisé pour un cercle défini par 2 points : le centre et un point quelconque situé sur la circonférence.

Le mot clé POLY sera utilisé pour un polygone défini par un maximum de 100 vecteurs : on donne l'adresse de chaque extrémité du vecteur.

Les coordonnées des points sont exprimées en pixels, la valeur de X et Y étant séparée par une virgule et chacun des points séparé par un expace.

Exemple d'une image cliquable que l'on verra plus loin de cette leçon :

Dans l'exemple ci-dessus, l'image "fond.gif" se compose d'un rectangle gris, dans lequel on trouve trois figures ; on souhaite qu'un clic sur le rectangle provoque une connexion sur le serveur http://www.informatique.fr, et un autre clic sur la flèche provoque une connexion au serveur http://www.geometrie.fr et encore un autre clic sur le cercle provoque une connexion au serveur http://www.physique.fr.

Le retour à l'URL locale /home_page.html doit être obtenu, en cliquant sur n'importe quelle autre zone de l'image.

- La première étape consiste à créer le fichier décrivant les relations entre les surfaces cliquables et les URL à atteindre :

défault /home_page.html

rect http://www.informatique.fr 5,5 21,14

poly http://www.geometrie.fr 38,6 50,6 48,18 42,15 40,21 35,14

circle http://www.physique.fr 52,32 45,32

Ce fichier sera enregistré par exemple sous le nom troisCliquables.map dans un répertoire du serveur dont le nom pourrait être /map.

Notez bien que ce fichier n'a rien de commun avec un fichier HTML. Nous allons voir maintenant comment il sera utilisé pour rendre l'image cliquable.

La possibilité de gérer des images cliquables n'est pas due à une fonctionnalité intrinsèque du serveur WEB (le démon HTTPD). Pour effectuer une telle opération, il faut exécuter un programme particulier, imagemap en l'occurence, qui a dû être précédemment installé par l'administrateur dans la zone CGI du serveur que l'on verra ultérieurement au cours de nos leçons concernant la programmation CGI.

Précisons d'emblée qu'il n'est pas nécessaire d'être informaticien ou de connaître la programmation pour réaliser des images cliquables. La manipulation la plus complexe reste l'écriture du fichier xxx.map que nous venons d'expliquer mais que l'on verra par la suite de nos leçons.

On doit maintenant déclarer le fichier troisCliquables.map dans un fichier du serveur imagemap.conf - situé à la racine du serveur. Ce fichier est connu du programme imagemap et va contenir ligne par ligne, sous un nom symbolique, l'adresse de tous les fichiers définissant les images cliquables du serveur. On édite donc le fichier imagemap.conf et on lui ajoute une ligne dans laquelle on le déclare, en lui attribuant un nom symbolique et en donnant son chemin d'accès.

Extrait du fichier imagemap.conf :

. . . . .

. . . . .

troisCliquables: /map/troisCliquables.map

- L'opération suivante consiste à proposer la carte cliquable dans la page HTML. La syntaxe générale sera la suivante :

<A HREF="cgi-bin/imagemap/nom_symbolique">

<IMG SRC="URL_image.gif" ISMAP>

</A>

L'attribut ISMAP indique au browser qu'il est en présence d'une carte cliquable et qu'il faudra qu'il relève les coordonnées du point cliqué.

Appliqué à notre exemple, cela donnera :

<A HREF="/cgi-bin/imagemap/troisCliquables">

<IMG SRC="fond.gif" ISMAP>

</A>

- La dernière opération consiste à tester l'image en cliquant sur chacune des zones prédéfinies, y compris sur la zone par défaut, pour vérifier le bon fonctionnement de l'ensemble.

Comment fonctionne une carte cliquable ?

A la demande du browser, le serveur envoie l'image cliquable. L'Internaute clique sur une zone de l'image ; grâce à l'attribut ISMAP, le browser récupère les coordonnées de l'image, puis déclenche l'accès vers l'URL cgi_bin/imagemap en passsant les paramètres suivants : le nom symbolique du fichier xxx.map les coordonnées X et Y du point cliqué. Le programme imagemap ouvre le fichier imagemap.conf et retrouve l'adresse réelle du fichier xxx.map qu'il va ouvrir. Il compare le couple X,Y avec les différentes zones définies dans ce fichier et détecte ainsi l'URL demandée. Il effectue alors la connexion vers cette URL.

Méthode N° 2 - usemap :

La réalisation de ce type de carte est beaucoup plus aisée, car tout est inclus, dans la page HTML et il n'est pas nécessaire de disposer d'un programme spécial sur le serveur. Une carte cliquable réalisée avec cette méthode peut être testée avec un simple browser, hors de l'environnement d'un serveur.

Dans la première méthode, c'est le serveur qui a la charge de détecter, à partir des coordonnées du point saisi, l'URL à connecter.

Avec cette seconde méthode, lorsque le client a reçu la page HTML, il traitera entièrement la détection du point saisi, puis il effectuera la connexion vers l'URL détectée. Outre la simplification de programmation, ce second mode est beaucoup plus efficace puisqu'il minimise les accès sur le réseau.

L'image est définie avec la balise <IMG> à laquelle est associé l'attribut USEMAP. Cet attribut permet de référencer un "sous-programme HTML" décrivant les zones cliquables et leurs URL associées.

La syntaxe d'appel sera donc :

<IMG SRC="image.gif" USEMAP="nom">

Le code de description de la carte se situe entre les balises <MAP NAME="nom"> et </MAP>

Entre ces deux balises, on dispose les balises <AREA SHAPE="figure" HREF="url" COORD="X0,Y0, X1,Y1, . . ."> pour décrire les zones cliquables.

Figure peut prendre les valeurs RECT, POLY ou CIRCLE ; les coordonnées sont décrites comme dans la figure 1 ci-dessus.

Il est possible de remplacer l'attribut HREF par NOHREF pour une zone neutre de l'image.

Exemple d'utilisation d'une carte cliquable :

<HTML>

<HEAD>

<TITLE> Image cliquable (usemap) </TITLE>

</HEAD>

<BODY>

<CENTER> <H3> Vous pouvez cliquer sur les inscriptions "Batterie" et "AMR", car c'est une carte cliquable en deux endroits (URL) ! </H3>

<img src="images/Carte_Mere_Cliquable.gif" usemap="#boutons" border="0"> </CENTER>

<map name="boutons">

<area shape="rect" href="http://www.electronique-et-informatique.fr/" TITLE="Cliquez ici" coords="300,100,340,220">

<area shape="rect" href="http://electronique-et-informatique.fr/sommaire_electronique_fondamentale.html" TITLE="Cliquez ici" coords="250,50,155,77">

</map>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

JavaScript et les images cliquables :

L'apport de JavaScript sur les images cliquables est essentiellement visuel. Dans une image cliquable classique, l'illustration une foie affichée à l'écran reste statique. En utilisant un Script Java, on pourra modifier dynamiquement, au passage de la souris, la portion de l'image correspondante à la zone sensible délimitée par la balise <area>.

Les événements de la balise <AREA>

Les deux événements de la balise <AREA> sont les suivants :

  • onMouseOver apparaît lorsque la souris entre dans le champ.

  • onMouseOut apparaît lorsque la souris sort du champ.

Ces deux événements sont insérés dans la balise <AREA> de la même façon que n'importe quel attribut, la valeur de l'attribut étant le nom de la fonction, avec entre parenthèses, la liste des paramètres passés à la fonction.

<AREA SHAPE="rect" coords="0,0,50,50" onMouseOver="affiche(1)" onMouseOut="affiche(0)" HREF="cible.html">

Lorsque le pointeur de la souris entre (onMouseOver) dans l'espace de coordonnées (0,0,50,50) de l'image, on effectue la fonction "affiche", qui reçoit alors la valeur 1 en paramètre d'entrée. De la même manière, lorsque le pointeur de la souris quitte (onMouseOut) cet espace, on effectue la même fonction "affiche", qui reçoit maintenant la valeur 0 en paramètre d'entrée. Bien sûr, il aurait été tout à fait possible d'appeler des fonctions différentes pour chacun des événements.

Rappels sur l'objet image :

Voir nos leçons JavaScript la fonction Image() que l'on verra par la suite et que nous avons programmé à cet effet.

Pour l'instant, avant d'étudier comment modifier l'aspect de l'image, en fonction des mouvements du pointeur de la souris, rappelons quelques concepts sur les images :

  • Les images qui apparaissent dans le browser sont des objets au sens JavaScript ayant un certain nombre de propriétés (hauteur, largeur, adresse du fichier contenant l'image, nom, etc.).

  • Pour créer une entité capable de recevoir le contenu d'un fichier graphique, il existe une fonction JavaScript de construction d'un objet image : new Image(). Une des propriétés de l'objet image, SRC, permet de spécifier l'URL du fichier graphique qui sera chargé dans cet objet image. On peut ainsi expliquer le code suivant :

menu1 = new Image();

menu.src ="zone1.gif"

La première ligne n'a d'autre effet que de créer un objet image vide dont le nom est "menu1".

La seconde instruction permet de précharger cet objet avec une image réelle "zone1.gif". Cela a pour résultat de charger dans le cache du browser une image dont le nom est "menu1" ; à ce moment-là, aucun affichage n'est réalisé. Simplement, à la fin du chargement de la page (code HTML et code JavaScript), une image est disponible dans le cache (mémoire) sans accès vers le serveur pour pouvoir l'afficher.

  • Il est possible de référencer les images affichées sur une page comme un tableau. Ainsi, si une page comporte trois images, on peut les référencer en partant du haut de la page par :

document.images[0] document.images[1] document.images[2]

A noter : Cache signifie un ensemble de mémorisation (mémoire RAM et disque) géré par le browser et permettant de stocker temporairement les dernières pages accédées.

Réalisation d'une carte cliquable animée :

Nous allons étudier comment utiliser les événements onMouseOver et onMouseOut pour faire changer l'image lors du passage du pointeur de la souris. Le problème peut se décomposer en plusieurs étapes :

  • On créera d'abord autant d'images de mêmes dimensions que de zones sensibles devant être animées. L'image Zone_0.png est l'image initiale affichée en l'absence de mouvement du pointeur de la souris. Dans notre exemple, on décide de travailler sur six zones, soit sept images en comptant celle au repos.

  • On détermine les coordonnées des zones sensibles.

  • On écrit le fichier Apercu_2_Menu_Anime.html (dans notre exemple) contenant le code HTML et le code JavaScript suivant :

Exemple d'utilisation d'une carte cliquable animée :

<HTML>

<HEAD>

<TITLE> Image cliquable anim&eacute;e </TITLE>

<SCRIPT LANGUAGE="JavaScript">

/* Le code situ&eacute; entre ce commentaire et la fonction "AFFICHE" est ex&eacute;cut&eacute; au chargement de la page */

/* Cr&eacute;ation des images */

menu0 = new Image();

menu1 = new Image();

menu2 = new Image();

menu3 = new Image();

menu4 = new Image();

menu5 = new Image();

menu6 = new Image();

/* Chargement des images dans le cache */

menu0.src ="images/Zone_0.png"

menu1.src ="images/Zone_1.png"

menu2.src ="images/Zone_2.png"

menu3.src ="images/Zone_3.png"

menu4.src ="images/Zone_4.png"

menu5.src ="images/Zone_5.png"

menu6.src ="images/Zone_6.png"

function affiche (num) {

/* Fonction appel&eacute;e par les &eacute;v&eacute;nements onMouseOver et onMouseOut */

if (num == "0") document.images[0].src = menu0.src;

else if (num == "1") document.images[0].src = menu1.src;

else if (num == "2") document.images[0].src = menu2.src;

else if (num == "3") document.images[0].src = menu3.src;

else if (num == "4") document.images[0].src = menu4.src;

else if (num == "5") document.images[0].src = menu5.src;

else if (num == "6") document.images[0].src = menu6.src;

}

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#000000" link="#FF0000" alink="#FFFF00" vlink="#00FF00">

<BR> <BR>

<font color="#00FFFF"> <H2> <CENTER> SOMMAIRE MENU ANIM&Eacute; </CENTER> </H2> </font>

<BR>

<p> <CENTER> <A HREF="Sommaire_HTML_Programmes.html"> RETOUR AU SOMMAIRE HTML</A> </CENTER> </p>

<BR> <BR>

<MAP NAME="Images_Animees">

<AREA SHAPE="rect" coords="19,4,160,31" href="Chemin_1.html" TITLE="Cliquez ici" onMouseOver="affiche(1)" onMouseOut="affiche(0)">

<AREA SHAPE="rect" coords="21,45,180,70" href="Chemin_2.html" TITLE="Cliquez ici" onMouseOver="affiche(2)" onMouseOut="affiche(0)">

<AREA SHAPE="rect" coords="11,105,228,87" href="Chemin_3.html" TITLE="Cliquez ici" onMouseOver="affiche(3)" onMouseOut="affiche(0)">

<AREA SHAPE="rect" coords="22,120,330,140" href="Chemin_4.html" TITLE="Cliquez ici" onMouseOver="affiche(4)" onMouseOut="affiche(0)">

<AREA SHAPE="rect" coords="25,155,430,175" href="Chemin_5.html" TITLE="Cliquez ici" onMouseOver="affiche(5)" onMouseOut="affiche(0)">

<AREA SHAPE="rect" coords="25,200,423,215" href="Chemin_6.html" TITLE="Cliquez ici" onMouseOver="affiche(6)" onMouseOut="affiche(0)">

</MAP>

<IMG SRC="images/Zone_0.png" USEMAP="#Images_Animees" border="0">

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Nous avons créé six pages HTML dont le contenu du code est le même pour toutes les pages, sauf le titre qu'il faudra "changer dans vos travaux, si vous faites des essais dans ce genre" ou que vous avez l'attention d'en faire un ou plusieurs sites selon votre guise. . . .

Nous vous rappelons que tous nos programmes HTML peuvent être insérés dans un bloc note sans pour autant d'avoir un logiciel spécifique pour l'HTML.

Nous mettons les six documents HTML nommés ci-dessous, et que vous verrez également dans la barre d'adresse les noms d'URL des mêmes pages concernées.

  • Chemin_1.html

  • Chemin_2.html

  • Chemin_3.html

  • Chemin_4.html

  • Chemin_5.html

  • Chemin_6.html

Bien évident, vous pouvez changer les noms des pages mais attention, vous devez changer les noms qui se trouvent dans le code HTML, en couleur bleue foncée, donc, à être très vigilant !

Nous mettons également les sept images concernant les menus ci-contre, afin que vous puissiez faire vos travaux ou encore des essais selon vos besoins.

A cet effet, vous pouvez changer les couleurs ou modifier selon votre choix, car les goûts de chacun de nous, sont totalement différent !

Dans le code HTML ci-dessus de l'exemple 2, on distingue deux parties dans la zone des scripts situé entre les balises <SCRIPT> et </SCRIPT>. La première se compose d'instructions JavaScript qui ne sont pas dans une structure de fonction. Ces instructions sont exécutées dès le chargement de la page HTML. Il en résulte un transfert de toutes les images depuis le serveur vers le cache du browser. La seconde partie est une fonction qui s'exécutera au moment où le pointeur de la souris entre ou sort d'une zone sensible.

Dans le code HTML, on trouve la définition standard d'une image cliquable. Cette image affichée au chargement de la page est la même que celle qui s'activera lorsque le pointeur de la souris sortira du champ. Comme c'est la première (et la seule) de la page, elle se référence par "document.images[0].src = menu0.src;". D'où image "Zone_0.png" se chargera dans le browser, "voir le programme ci-dessus de l'exemple 2".

Le fonctionnement est maintenant très simple : le pointeur de la souris entre dans une zone sensible, par exemple la troisième ; on appelle alors la fonction "affiche", en lui passant la valeur 3. Cette valeur est reçue par la fonction, qui, au cours de sa série de tests, va détecter que pour la valeur 3, il faut attribuer à l'objet image "document.images[0].src=menu3.src;" une nouvelle propriété (modification de la propriété "SRC"). Comme pour cela, il s'agit simplement de modifier un pointeur sur une image en mémoire (les images sont dans le cache), la substitution est instantanée.

Le scénario est le même pour le pointeur de la souris sortant de la zone, on substituera toujours l'image "Zone_0.png".

Remarque :

Que se passe-t-il si les images n'ont pas toutes la même taille ? L'image d'origine "document.images[0].src = menu0.src;" dans l'exemple précédent a une taille définie. si on lui substitue des images de tailles différentes, celles-ci vont s'ajuster à cette taille d'origine, donc s'agrandir ou se déduire. Ce qui n'est pas tellement formidable lorsque les images varient en large ou en hauteur sur le plan technique.

Nous résumons cette leçon ci-après :

Une image cliquable est définie par l'ensemble de balises suivant :

Méthode ISEMAP :

<A HREF="/cgi-bin/imagemap/nom_symbolique">

<IMG SRC="url_du_fichier.gif" ISMAP>

</A>

/cgi-bin/imagemap/ est un programme devant être préalablement installé dans le serveur WEB pour pouvoir proposer des images cliquables.

imagemap.conf est un fichier installé à la racine du serveur dans lequel on va référencer sous un nom_symbolique l'adresse réelle du fichier dans lequel sont décrites les relations entre les zones cliquables et leurs URL associées.

Ce fichier de relations s'écrit de la façon suivante :

forme URL X1,Y1,X2,Y2 ...

Le couple Xn, Yn définit les coordonnées d'un point de la forme utilisée. Il existe trois types de formes géométriques pour définir une zone cliquable :

CIRCLE X1, Y1, X2, Y2 - Le point 1 spécifie le centre du cercle, le point 2, un point quelconque situé sur le périmètre.

RECT X1, Y1, X2, Y2 - Le point 1 spécifie le sommet supérieur gauche, le point 2 spécifie le sommet inférieur droit.

POLY X1, Y1, X2, Y2, ... Xn, Yn - Chaque point définit l'extrémité d'un vecteur composant le polygone.

L'unité de mesure utilisée est le pixel

Méthode USEMAP :

<IMG SRC="url_du_fichier.gif" USEMAP="#nom">

USEMAP définit l'adresse d'une zone de code HTML dans laquelle sont décrites les surfaces cliquables et les URL associées.

Cette zone débute par la balise <MAP NAME="Nom"> et se termine par la balise </MAP>.

Entre ces deux balises, on définit les zones cliquables par des balises <AREA SHAPE="Figure" HREF="url" COORDS="coordonnées".>

Les coordonnées des figures ( RECT, POLY, CIRCLE) sont toujours exprimées en pixels.

Les événements associés à la balise <AREA> sont :

  • onMouseOver

  • onMouseOut.

Fin de cette onzième leçon, la prochaine sera consacrée aux Tableaux concernant le langage HTML.


Les Tableaux HTML

Les Tableaux HTML :

HTML permet de réaliser des tableaux avec réglage de l'encadrement, de la taille et de l'espacement des cellules. Cette leçon décrit les principales balises permettant de présenter un tableau.

La définition de la structure d'un tableau est tout à fait comparable à celle des listes que nous avons vu jusqu'à présent. On définit une balise de début de tableau, puis on décrit le tableau ligne par ligne et enfin, on indique la balise de fin de tableau. Cette structure est suffisamment simple pour que le tableau soit facile à maintenir (modification du nombre de lignes et de colonnes).

Une cellule peut contenir les éléments suivants :

  • Texte

  • Listes

  • Images

  • Liens hypertextuel

  • Éléments de formulaire que l'on verra dans la prochaine leçon.

<TABLE> :

La balise <TABLE> permet l'ouverture d'un tableau et la balise de fin de tableau est spécifiée par </TABLE>. On peut indiquer les attributs suivants : BORDER, CELLPADDING, CELLSPACING, la valeur de ces attributs est spécifiée en point (pixels). Leur spécification est indiquée à la figure 1 ci-dessus.

Un attribut supplémentaire permet de contraindre le tableau à occuper un certain pourcentage de la largeur de la fenêtre du browser. Il s'agit de l'attribut WIDTH.

Exemple d'utilisation d'un tableau N° 1 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER="6" CELLSPACING="6" CELLPADDING="10">

<H1> <font color="#005500"> Sans attribut WIDTH </font> </H1>

<TD> <H2> A </H2> </TD> <TD> <H2> B </H2> </TD> <TD> <H2> C </H2> </TD> <TR> <TD> <H2> D </H2> </TD> <TD> <H2> E </H2> </TD> <TD> <H2> F </H2> </TD> </TR>

<TABLE BORDER="6" WIDTH = "65%" CELLSPACING="6" CELLPADDING="10"> <BR> <BR> <BR> <TR VALIGN="CENTER" ALIGN="CENTER">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 65% </font> </H1>

<TD> <H2> A </H2> </TD> <TD> <H2> B </H2> </TD> <TD> <H2> C </H2> </TD>

<TR VALIGN="CENTER" ALIGN="CENTER"> <TD> <H2> D </H2> </TD> <TD> <H2> E </H2> </TD> <TD> <H2> F </H2> </TD> </TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

<TR> :

La balise <TR> débute une ligne du tableau qui sera terminée par une balise de fin </TR>. Elle admet l'attribut VALIGN, pour obtenir un alignement du texte dans le sens vertical de la cellule, ALIGN pour l'alignement horizontal. Ces attributs d'alignement s'appliquent pour toutes les cellules de la ligne, sauf si un attribut de <TD> vient contredire l'alignement.

Les valeurs prises par les attributs d'alignement peuvent être : TOP (haut), BOTTOM (bas), MIDDLE (centrage vertical), RIGHT (droite), CENTER (centré horizontalement), LEFT (gauche). Ceci est valable pour l'ensemble des balises.

<TR VALIGN="center" ALIGN="left"> <TD> 1 </TD> <TD> 10 </TD> <TD> 100 </TD> <TD> 1 000 </TD> <TD> 10 000 </TD> <TD> 100 000 </TD>

Exemple d'utilisation d'un tableau N° 2 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 2 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER="6" CELLSPACING="6" CELLPADDING="10">

<H1> <font color="#005500"> Sans attribut WIDTH </font> </H1>

<TR VALIGN="center" ALIGN="left"> <TD> 1 </TD> <TD> 10 </TD> <TD> 100 </TD> <TD> 1 000 </TD> <TD> 10 000 </TD> <TD> 100 000 </TD>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

<TD> :

La balise <TD> délimite le début d'une cellule. Elle admet l'attribut VALIGN, pour obtenir un alignement du texte dans le sens vertical de la cellule, ALIGN pour l'alignement horizontal, COLSPAN pour définir une cellule dont la largeur est un multiple de la colonne de base, et ROWSPAN pour définir une cellule dont la hauteur est un multiple de la ligne (voir illustration de l'utilisation de rowspan et colspan, ci-dessous figure 2.

<TR ALIGN="LEFT"> <TD> 10 </TD> <TD ALIGN="CENTER"> 100 </TD> <TD ALIGN="RIGHT"> 1 000 </TD> </TR>

Exemple d'utilisation d'un tableau N° 3 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 3 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER = "6" WIDTH = "50%" CELLSPACING = "6" CELLPADDING = "10">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 50% </font> </H1>

<TR ALIGN="LEFT"> <TD> 10 </TD> <TD ALIGN="CENTER"> 100 </TD> <TD ALIGN="RIGHT"> 1 000 </TD> </TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Dans les tableaux, l'ajustement de la taille des cellules est automatique, la largeur d'une cellule dépend du plus long texte inscrit dans une des cellules de la colonne.

Par défaut, si la ligne est trop longue (> 64 caractères) très dépendant du browser mais ce dernier, la coupe en plusieurs lignes selon les navigateurs.

L'attribut NOWRAP de la balise <TD> force le browser à inscrire tout le texte de la cellule sur une seule ligne.

Exemple d'utilisation d'un tableau N° 4 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 4 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER = "6" WIDTH = "50%" CELLSPACING = "6" CELLPADDING = "10">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 50% Sans NOWRAP</font> </H1>

<TR> <TD align="CENTER"> <i> Cahier &agrave; spirales de couleur verte, au format de 21 cm par 29,7 cm.

150 Pages, petits carreaux papier 100 grammes et couverture tr&egraves jolie. </i> </TD> <TD ALIGN="CENTER"> 100 </TD> <TD ALIGN="RIGHT"> 1000 </TD> </TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Exemple d'utilisation d'un tableau N° 5 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 5 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER = "6" WIDTH = "50%" CELLSPACING = "6" CELLPADDING = "10">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 50% AVEC NOWRAP</font> </H1>

<TR> <TD align="CENTER" NOWRAP> <i> Cahier &agrave; spirales de couleur verte, au format de 21 cm par 29,7 cm.

150 Pages, petits carreaux papier 100 grammes et couverture tr&egraves jolie. </i> </TD> <TD ALIGN="CENTER"> 100 </TD> <TD ALIGN="RIGHT"> 1000 </TD> </TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

Illustration de l'utilisation de ROWSPAN et COLSPAN :

<TR ALIGN="CENTER"> <TD> </TD> <TD> </TD> <TD> <H1> A </H1> </TD> <TD> <H1> B </H1> </TD> <TD> <H1> C </H1> </TD> </TR>

<TR ALIGN="CENTER"> <TD ROWSPAN="2" COLSPAN="2"> <H1> 1 </H1> </TD> <TD> <H1> D </H1> </TD> <TD> <H1> E </H1> </TD> <TD> <H1> F </H1> </TD> </TR>

<TR ALIGN="CENTER"> <TD> <H1> G </H1> </TD> <TD> <H1> H </H1> </TD> <TD> <H1> I </H1> </TD>

Exemple d'utilisation d'un tableau N° 6 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 6 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER = "6" WIDTH = "50%" CELLSPACING = "6" CELLPADDING = "10">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 50% </font> </H1>

<TR ALIGN="CENTER"> <TD> </TD> <TD> </TD> <TD> <H1> A </H1> </TD> <TD> <H1> B </H1> </TD> <TD> <H1> C </H1> </TD> </TR>

<TR ALIGN="CENTER"> <TD ROWSPAN="2" COLSPAN="2"> <H1> 1 </H1> </TD> <TD> <H1> D </H1> </TD> <TD> <H1> E </H1> </TD> <TD> <H1> F </H1> </TD> </TR>

<TR ALIGN="CENTER"> <TD> <H1> G </H1> </TD> <TD> <H1> H </H1> </TD> <TD> <H1> I </H1> </TD>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6].

Remarquez bien que le tableau est construit sur une matrice de 5 par 3, et que l'on obtient des cases vides, en faisant suivre deux balises <TD> <TD>

<TH> :

La balise <TH> est identique à <TD>, mais le texte des cellules est considéré comme du texte d'en-tête. Il est automatiquement centré et est mis en caractères gras. Cette balise admet les mêmes paramètres que la balise <TD> (valign, align, colspan, rowspan, nowrap).

<TR> <TH> <font size="6" color="#800008"> Article </font> </TH> <TH> <font size="6" color="#800008"> R&eacute;f&eacute;rence </font> </TH> <TH> <font size="6" color="#800008"> Prix </font> </TH> <TH> <font size="6" color="#800008"> Quantit&eacute; </font> </TH> </TR>

<TR> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> <i> Cahier </i> </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 17 </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 12,54 &euro; </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 3 </font> </TD> </TR>

Exemple d'utilisation d'un tableau N° 7 :

<HTML>

<HEAD>

<TITLE> Exemple d'un tableau N&deg; 7 </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<TABLE BORDER = "6" WIDTH = "60%" CELLSPACING = "6" CELLPADDING = "10">

<H1> <font color="#005500"> Avec attribut WIDTH &agrave; 60% </font> </H1>

<TR> <TH> <font size="6" color="#800008"> Article </font> </TH> <TH> <font size="6" color="#800008"> R&eacute;f&eacute;rence </font> </TH> <TH> <font size="6" color="#800008"> Prix </font> </TH> <TH> <font size="6" color="#800008"> Quantit&eacute; </font> </TH> </TR>

<TR> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> <i> Cahier </i> </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 17 </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 12,54 &euro; </font> </TD> <TD ALIGN="CENTER"> <font size="6" color="#0000FF"> 3 </font> </TD> </TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

<CAPTION> :

Cette balise permet de placer un titre au-dessus (attribut ALIGN="TOP") ou au-dessous (attribut ALIGN="BOTTOM") du tableau.

<CAPTION ALIGN="BOTTOM">

<b> Fournitures </b>

</CAPTION>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

L'attribut BGCOLOR :

Cet attribut, selon qu'il est appliqué à la balise <TABLE>, à la balise <TR> ou à la balise <TD>, permet de donner une couleur de fond à un tableau, une ligne, ou à une cellule d'un tableau. La couleur est codée selon le modèle RGB.

Exemple de tableau intégrant divers éléments :

Exemple d'utilisation d'un tableau intégrant divers éléments N° 9 :

<HTML>

<HEAD>

<TITLE> Tableau Int&eacute;grant divers &Eacute;l&eacute;ments N&deg; 9 </TITLE>

</HEAD>

<BODY BGCOLOR="#E2E2E2" LINK="#FF0000" ALINK="#005500" VLINK="#800008">

<CENTER> <BR> <BR> <BR>

<font Face="Arial" size="6" color="#005500"> Bienvenue !!! </font>

<BR> <BR> <BR>

<TABLE BORDER="4" CELLSPACING="2" CELLPADDING="10" BGCOLOR="#CCCCCC">

<CAPTION ALIGN="BOTTOM">

<font face="Arial"> <b> Tableaux &agrave; &eacute;l&eacute;ments multiples ! </b> </font>

</CAPTION>

<TR ALIGN="CENTER">

<TD> <A HREF ="http://www.electronique-et-informatique.fr/sommaire_electronique_fondamentale.html"> <font face="Arial"> Sommaire &eacute;lectronique</A> </font> </TD>

<TD> <IMG SRC="images/PDF.gif"> </TD>

<TD> <font face="Arial"> <a href="Page_Tableaux.html"> <b>Retour</b></a> </font> </TD>

</TR>

<TR>

<TD ALIGN="CENTER"> <IMG SRC="images/W.gif"> </TD>

<TD>

<UL>

<LI> UN </LI>

<LI> DEUX </LI>

<LI> TROIS </LI>

<LI> QUATRE </LI>

<LI> CINQ </LI>

</UL>

</TD>

<TD ALIGN="CENTER">

<A HREF="Page_Tableaux.html"> <button type="submit"> <img src="images/Fleche_Gauche.PNG"> </A> </button>

</TD>

</TR>

<TR>

<TD ALIGN="CENTER"> <font face="Arial"> <i> Entrez votre Pr&eacute;nom et votre Nom </i> </font> </TD>

<TD ALIGN="LEFT">

<FORM METHOD="POST" ACTION="mailto:daniel.robe@orange.fr">

<font face="Arial"> Nom </font>&nbsp;&nbsp;&nbsp;&nbsp; <INPUT NAME="Votre_Nom"> <BR>

<font face="Arial"> Pr&eacute;nom </font> <INPUT NAME="Votre_Prenom">

<TD ALIGN="CENTER">

<INPUT TYPE="SUBMIT" VALUE="CLIC !">

</FORM>

</TD>

</TD>

</TR>

</TABLE>

<BR> <BR> <BR>

<font face="Arial" size="4" color="#000000"> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire</a> </font>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

Ce dernier exemple N° 9, nous avons créé deux pages HTML identiques, les codes restent les mêmes mis à part, le <TITLE> et <A HREF> qu'il faudra changer vos URL et selon vos besoins car, ce ne sont uniquement que des exemples.

Et enfin, nous allons résumer nos leçons des tableaux comme ci-après :

Résumé :

Un tableau quelconque se définit entre les balises <TABLE> et </TABLE>.

A l'intérieur de la première balise, on règle la présentation générale du tableau à l'aide de trois attributs :

  • BORDER définit l'épaisseur du cadre extérieur,

  • CELLPADDING définit l'espace autour du texte d'une cellule,

  • CELLSPACING définit l'espace entre les cellules,

  • WIDTH définit la largeur du tableau relativement à la largeur de la fenêtre du browser.

Le tableau est ensuite décrit ligne par ligne. L'élément définissant une nouvelle ligne est <TR>, qui admet les attributs d'alignement du texte à l'intérieur de toutes les cellules de la ligne :

VALIGN (Alignement vertical) peut prendre les valeurs suivantes :

  • TOP place le texte en haut de la cellule,

  • BOTTOM place le texte en bas de la cellule,

  • MIDDLE place le texte au centre de la cellule,

ALIGN (Alignement horizontal) peut prendre les valeurs suivantes :

  • RIGHT place le texte à droite de la cellule,

  • LEFT place le texte à gauche de la cellule,

  • CENTER place le texte au centre de la cellule,

  • </TR> termine la définition d'une ligne,

<TD> est l'élément de départ d'une colonne. Il peut être complété par des attributs VALIGN et ALIGN, qui seront alors prioritaires sur les mêmes valeurs définies dans la balise <TR>.

Deux attributs supplémentaires , COLSPAN et ROWSPAN, permettent de générer des cellules dont la surface est un multiple de la cellule élémentaire. La matrice du tableau définissant le nombre de cellules élémentaires est calculée par le nombre de lignes du tableau (nombre d'instructions <TR>), multiplié par le nombre de cellules (nombre d'instructions <TD> de la ligne définissant le plus de cellules (plus grand nombre de <TD>).

Le nombre de cellules par ligne du tableau est calculé sur la ligne définissant le plus de cellules.

Le dernier attribut de <TD> est NOWRAP, qui empêche de diviser le texte de la cellule en plusieurs lignes.

Enfin, la balise <TH> est une balise fonctionnant de façon similaire à la balise <TD> ; elle admet les mêmes attributs, mais est considérée comme balise de titre d'une cellule. Le centrage du texte et l'utilisation de caractères gras sont automatiques.

Un tableau peut recevoir un titre défini entre les balises <CAPTION> et </CAPTION>. Ce titre peut se situer au-dessus (attribut ALIGN avec la valeur TOP) ou en dessous (ALIGN avec la valeur BOTTOM).

On peut affecter une couleur à un tableau, une ligne ou une colonne à l'aide de l'attribut BGCOLOR.

Fin de cette douzième leçon, la prochaine sera consacrée aux frames concernant le langage HTML.


Les Frames HTML

Les Frames HTML :

Nous avons vu jusqu'à présent que, avec HTML, il est possible de créer des tableaux complexes, dont chaque cellule peut contenir indifféremment du texte, un formulaire, une image et bien d'autres encore ... Nous allons voir que les frames, introduites par certains browsers, et maintenant disponibles sur les principaux browsers du marché, apportent des fonctionnalités voisines des tableaux, encore plus puissantes. Le concept est simple. Comme avec les tableaux, il consiste à diviser l'écran du browser en plusieurs zones, appelées frames. Chacune d'elles est capable d'afficher du code HTML, comme c'est le cas dans les cellules d'un tableau. Il existe cependant une différence majeure. Dans un tableau, toutes les cellules font partie du même document HTML. Elles sont toutes issues d'un même fichier ou d'un même script CGI. Dans le cas des frames, chaque zone de l'écran est un document HTML propre. On voit donc simultanément, sur la même fenêtre d'un browser, la mise en page correspondant à plusieurs fichiers HTML différents. Un lien hypertexte peut alors mettre à jour certaines zones du browser sans modifier les autres. Chaque zone possédant un nom unique, il est simple d'indiquer quelle zone un lien hypertexte doit être modifié.

La notion de frame supprime l'une des limitations du Web. Auparavant, chaque nouveau document venait écraser le précédent, et obligerait bien souvent l'utilisateur à user et abuser de la commande "précédent" des browsers (back en anglais). Désormais, il est possible de dédier certaines zones du browser à des tâches bien précises. On peut imaginer, par exemple, une zone qui contienne une barre de menus et qui ne soit presque jamais rechargée. Ou encore, une autre zone utilisée pour afficher une aide contextuelle, sans que l'utilisateur perde la page sur laquelle il travaille.

Pour mieux comprendre ce nouveau concept, examinons un exemple. La page proposée est composée de trois zones (on parlera indifféremment dans cette leçon de zone ou de frame). La zone supérieure contient un formulaire de recherche. Celle de gauche affiche les résultats de la recherche. Quant à celle de droite, elle permet d'obtenir plus d'informations concernant un élément dans la liste des résultats. La soumission du formulaire de la zone supérieure met à jour la zone de gauche sous forme d'une liste de valeurs dont chaque élément est un lien hypertexte. Chaque lien hypertexte de la liste des résultats modifie la zone de droite. Cet écran permet donc de gérer simultanément trois documents HTML.

Pour donner un premier aperçu de la syntaxe utilisée, voici le cde HTML à l'origine de cet exemple :

Exemple d'utilisation d'une page intitulée "Apercu_1_de_Frame.html", dont le code HTML ci-dessous :

<HTML>

<HEAD>

<TITLE> Exemple d'un Annuaire </TITLE>

</HEAD>

<FRAMESET ROWS="235, *">

<FRAME SRC="Annuaire.html" MARGINWIDTH="25" MARGINHEIGHT="25" NORESIZE>

<FRAMESET COLS="48%, 50%">

<FRAME SRC="images/Livre.png" NAME="LISTE" MARGINWIDTH="35" MARGINHEIGHT="35">

<FRAME SRC="images/Livre.png" NAME="DETAIL" MARGINWIDTH="35" MARGINHEIGHT="35">

</FRAMESET>

<NOFRAMES>

Ce document contient des frames et votre browser est incapable de les g&eacute;rer ...

</NOFRAMES>

</FRAMESET>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1]. Dont nous expliquerons en détail au cours de nos leçons, car, en réalité, il y a 6 pages HTML.

Il est intéressant de noter que ce document ne contient aucune des informations qui vont être présentées à l'utilisateur. En fait, il ne contient que des informations destinées au browser. Avec ce document, le browser sait en effet quelles sont les frames qu'il doit créer et avec quels documents il doit les remplir. Si l'on regarde de plus près, par exemple, la définition de la zone ou frame supérieure, on note qu'elle doit recevoir le code HTML du document "Annuaire.html". Ce document est un document HTML classique, qui contient l'information à afficher à l'utilisateur. En voici le détail ci-après :

Exemple d'utilisation d'une page intitulée "Annuaire.html", dont le code HTML ci-dessous faisant parti du même document HTML, en [Exemple 1] ci-dessus :

<HTML>

<HEAD>

<TITLE> Annuaire </TITLE>

<STYLE TYPE="text/css"> /* Style interne */

<!-- A { color:#993300; text-decoration:none; }

A:hover { color:#005500;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#E2E2E2" LINK="#FF0000" ALINK="#FF00FF" VLINK="#800008">

<CENTER> <H1> FORMULAIRE &nbsp;&nbsp; - &nbsp;&nbsp; <a href="Sommaire_HTML_Programmes.php" TARGET="_TOP">Retour au sommaire PHP</a> </H1>

<FORM ACTION="Apercu_1_de_la_Frame_Gauche.html" METHOD="GET" TARGET="LISTE">

<p> <font face="Arial" size"4" color="#005500"> <b> Votre Pr&eacute;nom : </b>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <INPUT TYPE="text" NAME="LISTE" VALUE="" SIZE="22"> <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b> Votre Nom : </b>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <INPUT TYPE="text" NAME="DETAIL" VALUE="" SIZE="22"> <BR>

<b> Votre Adresse : </b>

&nbsp;&nbsp;&nbsp;&nbsp; <INPUT TYPE="text" NAME="recherche" VALUE="" SIZE="22"> <BR> </font> </p>

&nbsp;&nbsp;&nbsp;&nbsp; <BUTTON TYPE ="SUBMIT"> <img src="images/Fleche_Gauche.PNG"> </BUTTON>

</CENTER>

</FORM>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2]. Découpage de notre document frame.

On remarque toutefois un nouvel attribut pour la balise <FORM>, l'attribut TARGET, qui indique tout simplement le nom de la zone dans laquelle sera affiché le résultat de la soumission du formulaire.

A noter : Si vous voulez changer les noms des pages HTML, il faudra également envisager de changer les noms dans le code HTML.

Création de frames :

En fait, seules trois nouvelles balises ont été ajoutées au langage HTML afin d'apporter cette nouvelle fonctionnalité. Cependant, la structure générale d'un document divisé en plusieurs frames diffère de celle d'un document classique. Dans un document classique, le corps est inséré dans les balises <BODY> ... </BODY>. Dans le cas des frames, le corps du document est systématiquement inséré dans les balises <FRAMESET> ... </FRAMESET>, <FRAME> et <NOFRAMES>.

Nous attirons votre attention que si vous mettez une balise <BODY> dans une frame par exemple, avec une balise <FRAMESET>, cela ne pourra pas fonctionner.

Exemple de document classique contenant l'information à afficher à l'utilisateur (texte, images, formulaires ...)

<HTML>

<HEAD>

<TITLE> . . . . . . </TITLE>

. . . . . .

</HEAD>

<BODY>

. . . . . .

</BODY>

</HTML>

Exemple de document de définition de frames ne contenant aucune information destinée à l'utilisateur, mais uniquement des informations destinées au browser (géométrie des différentes frames et document HTML associé).

<HTML>

<HEAD>

<TITLE> . . . . . . </TITLE>

. . . . . .

</HEAD>

<FRAMESET . . . >

<FRAMESET . . . >

. . .

</FRAMESET . . . >

. . .

<FRAMESET . . . >

<FRAME . . . >

</FRAMESET . . . >

<FRAME . . . >

</FRAMESET . . . >

</HTML>

<FRAMESET> :

<FRAMESET> est la balise d'ouverture permettant de diviser une zone en sous-zone, soit verticalement, soit horizontalement. Si aucune zone n'est encore définie, les divisions s'appliquent à la zone initiale formée par l'ensemble de la fenêtre du browser. Cette balise possède les attributs suivants :

ROWS est utilisé pour diviser la zone en sous-zones horizontales. La syntaxe est la suivante :

ROWS="hauteur_zone_1, hauteur_zone_2, hauteur_zone_n"

ROWS est une liste de valeurs entières séparées par des virgules. Le nombre d'éléments de la liste correspond au nombre de sous-zones horizontales à créer. Chacune des valeurs de la liste peut être donné selon l'un des trois formats suivants, dans lesquels n est un nombre entier :

  • n : la valeur de n indique la hauteur de la sous-zone en nombre de pixels ;

  • n% : n indique ici la hauteur de la sous-zone exprimée en pourcentage de la taille de la zone mère ;

  • n* : ici, n est optionnel ; le caractère * indique au browser qu'il doit donner à la sous-zone la place encore disponible. Lorsque plusieurs éléments de la liste utilisent ce format, la place sera encore disponible est répartie entre les sous-zones correspondantes. n pourra alors être utilisé pour indiquer au browser qu'une sous-zone doit recevoir une proportion n fois surpérieure de la place encore disponible.

COLS est utilisé pour diviser la zone en sous-zones verticales. La syntaxe est en tous points identique à celle de l'attribut ROWS :

COLS="largeur_zone_1, largeur_zone_2, largeur_zone_n"

Voici par exemple deux manières identiques de diviser une zone en trois. Les deux sous-zones supérieures sont de taille identique, égale à la moitié de la zone inférieure :

FRAMEBORDER est utilisé pour indiquer si la frontière entre deux frames doit avoir un effet 3D (un effet d'ombre). La valeur par défaut est "yes", si bien que les bordures de frames possèdent en général un effet 3D. La syntaxe est la suivante :

FRAMEBORDER="NO/YES"

BORDER indique, dans le cas où FRAMEBORDER vaut "no", la largeur de la bordure entre deux frames. La valeur 0 supprime les bordures de frames. La syntaxe est la suivante :

MARGINWIDTH="n"

BORDERCOLOR indique, dans le cas où FRAMEBORDER vaut "yes", la couleur des bordures de frames. La syntaxe est la suivante :

BORDERCOLOR="couleur"

Insérées entre les balises <FRAMESET> . . . </FRAMESET>, on ne peut trouver que les trois balises suivantes :

  • <FRAMESET> . . . </FRAMESET>, qui permet de rediviser une sous-zone ;

  • <FRAME . . . > qui est utilisée pour caractériser une sous-zone ;

  • Et enfin, <NOFRAME> . . . </NOFRAME>, qui permet d'afficher un texte à la place des frames si le browser n'est pas capable de les gérer.

Aucune autre balise HTML ne peut être acceptée.

<FRAME> :

<FRAME> est la balise utilisée pour caractériser les sous-zones définies à l'aide de la balise <FRAMESET>. Cette caractérisation est réalisée à l'aide de six attributs :

SRC indique l'URL du document qui doit être affiché dans cette zone. Si cet attribut n'est pas précisé, la zone reste vide. La syntaxe est la suivante :

SRC="URL"

NAME est utilisé pour nommer la zone afin qu'elle puisse devenir la cible de n'importe quel lien hypertexte. Sinon, cela ne peut fonctionner. Les noms prédéfinis, _blank, _top, _parent, _self ainsi que tous les noms commençant par le "caractère de suite" '_' ne peuvent pas être utilisés pour renseigner cet attribut. La syntaxe de l'attribut NAME est ci-après :

NAME="nom_de_la_zone"

MARGINWIDTH est utilisé pour préciser le nombre de pixels entre les frontières gauche et droite de la zone et le document HTML à afficher. La syntaxe est la suivante :

MARGINWIDTH="n"

MARGINHEIGHT est utilisé pour préciser le nombre de pixels entre les frontières haute et basse de la zone et le document HTML à afficher. La syntaxe est la suivante :

MARGINHEIGHT="n"

Exemple :

SCROLLING indique si la zone doit posséder une barre de défilement (SCROLLING="yes") ou non (SCROLLING="no"), ou encore si ce choix est laissé au browser (SCROLLING="auto"). La syntaxe est la suivante :

SCROLLING="yes/no/auto"

NORESIZE n'a pas de valeur. Sa présence indique uniquement au browser qu'il doit empêcher toute modification de la taille d'une zone. Lorsque cet attribut n'est pas précisé, il est toujours possible de déformer une zone, en déplaçant sa frontière à l'aide du pointeur de la souris.

<NOFRAMES> :

<NOFRAMES> est une balise qui indique à tout browser ne soit incapable de gérer les frames le texte qu'il doit présenter à l'utilisateur à la place de la frame. ce texte est bien sûr ignoré par un browser capable de gérer les frames. En fait, le fonctionnement de cette balise est simple. Les browsers Web ne tiennent compte que des balises qu'ils connaissent. Un browser qui ne sait pas gérer les frames ignorera donc les balises <FRAMESET>, </FRAMESET>, <FRAME> et également <NOFRAMES> et </NOFRAMES>. Or, si on retire toutes ces balises d'un document contenant des frames, on voit qu'il ne reste plus que le texte qui était compris entre les balises <NOFRAMES>. . . </NOFRAMES>

Au contraire, un browser capable de gérer des frames interprétera les balises <NOFRAMES> . . . </NOFRAMES> et saura qu'il doit ignorer le texte compris entre ces balises.

Voici deux exemples illustrant la facilité d'utilisation des frames. On suppose que le fichier Test_Frames.html utilisé pour renseigner l'attribut SRC des balises <FRAME> est un fichier HTML classique.

Premier exemple ; ce qui donne ceci :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Exemple d'utilisation d'une page intitulée "Test_Frames_2.html", dont vous trouverez une partie du code HTML ci-dessous, correspondant uniquement aux frames ... :

Deuxième exemple ; ce qui donne ceci :

<HTML>

           <HEAD>

               <TITLE> 2&egrave;me Exemple d'un Test Frame </TITLE>

           </HEAD>

                    <FRAMESET ROWS = "*, *, *">

                    <FRAME SRC = "Name_Haut_1.html">

                    <FRAMESET COLS ="3 *, *">

                    <FRAME SRC ="Name_Sous_Haut_Gauche.html">

                    <FRAME SRC ="Name_Droite_1.html">

                    </FRAMESET>

                    <FRAMESET COLS = " *, *, 2 *">

                    <FRAME SRC = "Name_Gauche.html">

                    <FRAME SRC = "Name_Sous_Gauche.html">

                    <FRAME SRC = "Name_Droite.html">

                    </FRAMESET>

                    <NOFRAMES>

                    Ce document contient des frames et votre browser est incapable de les g&eacute;rer ...

                    </NOFRAMES>

                    </FRAMESET>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Utilisation des frames :

Maintenant que nous avons vu en détail, comment créer des documents divisés en frames, nous allons voir comment créer des liens hypertexte utilisant ces frames.

L'attribut TARGET :

En plus des trois nouvelles balises décrites ci-dessus, un nouvel attribut a été créé. Il concerne les balises caractérisant des liens hypertexte, en particulier les balises <A> et <FORM>. Il s'agit de l'attribut TARGET, qui permet de préciser le nom de la zone qui doit recevoir le document correspondant au lien. Considérons par exemple le lien hypertexte suivant :

<A HREF="/dossier.html" TARGET="zonedossier">Voir le dossier</A>

L'attribut est là pour indiquer au browser qu'en réponse à un clic, il doit afficher le document dossier.html dans la frame dont le nom est "zonedossieré" (c'est-à-dire la frame qui a été définie par la balise <FRAME NAME="zonedossier"... >). De la même façon, la soumission du formulaire défini par :

<FORM ACTION="Apercu_1_de_la_Frame_Gauche.html" METHOD="GET" TARGET="LISTE">

</FORM>

Affichera ses résultats dans la frame dont le nom est "LISTE".

On peut isoler trois cas pour décrire les valeurs possibles de l'attribut TARGET.

Dans le premier cas, l'attribut TARGET a une valeur qui correspond au nom d'une frame existante. Le document associé au lien hypertexte est alors affiché dans la frame en question.

Dans le deuxième cas, l'attribut TARGET a une valeur qui ne correspond à aucune des frames existantes. Le browser crée alors une nouvelle fenêtre (un nouveau browser) et y affiche le document. Cette nouvelle fenêtre est considérée comme une frame portant le nom de l'attribut TARGET à l'origine de sa création.

Dans le dernier cas, l'attribut TARGET prend une de ces quatre valeurs prédéfinies :

  • _blank, qui est utilisé pour indiquer au browser qu'il doit créer une nouvelle fenêtre (c'est-à-dire un nouveau browser) afin d'afficher le document. Le nouveau browser est une frame qui ne porte pas de nom et ne peut donc pas être la cible d'un autre lien hypertexte ;

  • _self, qui indique que le document sera chargé dans la même zone que celle dans laquelle se trouve le lien hypertexte. Il s'agit de la valeur par défaut lorsque l'attribut TARGET n'est pas renseigné ;

  • _top, qui indique au browser de supprimer toutes les frames existantes et d'afficher le document de façon classique, en occupant toute la surface du browser ;

  • _parent, qui indique au browser d'afficher le document, en occupant toute la surface de la zone dans laquelle a été affiché le document contenant le lien. Cette notion n'a de sens que lorsque les différents niveaux de frames proviennent de l'imbrication de documents et non de l'imbrication des balises <FRAMESET>. Dans ce cas, un lien situé dans la frame "basdroite" par exemple, et ayant un attribut TARGET="_parent" provoquera l'affichage du document correspondant dans la frame "bas". Le document recouvrera dans les deux frames "basdroite" et "basgauche". dans ce cas précis, le même résultat aurait été obtenu avec un attribut TARGET="bas".

Afin de bien cerner la signification de ces valeurs prédéfinies (notamment celle de la valeur _parent, qui peut paraître un peu obscure à priori), voici un court exemple. Pour le comprendre plus vite, il est conseillé de créer sur votre serveur (ou plus simplement sur la machine où se trouve votre browser), les cinq fichiers qui composent cet exemple, puis d'ouvrir le document "Plus_Bas.html" avec un browser capable d'afficher des frames (Internet Explorer, Google Chrome, Opéra et bien d'autres encore).

Voici les cinq fichiers en question :

Descendre.html, Plus_Haut.html, Plus_Bas.html, A_Droite.html et A_Gauche.html

Le fichier Descendre.html est un document constitué de deux frames horizontales de même taille. La frame supérieure affiche le document Plus_Haut.html et la frame inférieure, le document Plus_Bas.html :

<HTML>

           <HEAD>

               <TITLE> DESCENDRE </TITLE>

           </HEAD>

                    <FRAMESET ROWS = "*, *">

                    <FRAME SRC = "Plus_Haut.html">

                    <FRAME SRC = "Plus_Bas.html">

                    </FRAMESET>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

Le fichier Plus_Bas.html possède uniquement un lien hypertexte qui, lorsqu'il est activé, affiche dans la frame où il se trouve le document Descendre.html. Ceci a pour résultat de diviser la frame en deux sous-frames horizontales de taille égale.

Voici le code correspondant du document Plus_Bas.html :

<HTML>

           <HEAD>

               <TITLE> PLUS_BAS </TITLE>

           </HEAD>

          <BODY BGCOLOR="#373737" LINK="#FF0000" ALINK="#00FFFF" VLINK="#FF40FF"> <BR>

          <H2> <center> <font color="#FFFFFF"> "PLUS_BAS.HTML" <a href="http://www.electronique-et-informatique.fr/Electronique-et-Informatique/HTML_et_Programmes/Sommaire_HTML_Programmes.html" TARGET="_TOP">Retour au Sommaire HTML</a> </font> </center> </H2>

          <p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <font face="Arial" size="4"> <a href="Descendre.html">Plus bas</a> </font> </p>

          </BODY>

</HTML>

Le Fichier A_Droite.html est un document constitué de deux zones verticales de même taille. La frame de gauche affiche le document Plus_Haut.html et la frame de droite affiche le document Plus_Bas.html, en voici le code ci-après :

<HTML>

           <HEAD>

               <TITLE> ZONE GAUCHE </TITLE>

           </HEAD>

                    <FRAMESET COLS = "*, *">

                    <FRAME SRC = "Plus_Haut.html">

                    <FRAME SRC = "Plus_Bas.html">

                    </FRAMESET>

</HTML>

Le Fichier A_Gauche.html est un document constitué de deux zones horizontales de même taille. La frame de haut affiche le document Plus_Haut.html et la frame du bas affiche le document Plus_Bas.html, en voici le code ci-après :

<HTML>

           <HEAD>

               <TITLE> ZONE HAUTE </TITLE>

           </HEAD>

                    <FRAMESET ROWS = "*, *">

                    <FRAME SRC = "Plus_Haut.html">

                    <FRAME SRC = "Plus_Bas.html">

                    </FRAMESET>

</HTML>

Le dernier fichier, Plus_Haut.html, est un peu particulier. Il n'apparaît dans aucun des liens hypertexte des autres fichiers. Il est utilisé uniquement pour remplir une sous-frame du document Descendre.html ou A_droite.html ou encore A_Gauche.html. Il s'agit en quelque sorte d'un sous-document du document Descendre.html ou A_Droite.html ou encore celui A_Gauche.html. Pour un lien du fichier Plus_Haut.html, l'attribut TARGET="_parent" a alors un sens. Il indique au browser d'utiliser la frame du sur-document (dans notre cas, il s'agira de la frame contenant le document Descendre.html ou A_Droite.html ou encore A_Gauche.html) pour afficher le document correspondant aux liens hypertexte. On remplace ainsi le document Descendre.html ou A_Droite.html ou celui de A_Gauche.html par un autre document.

Examinons maintenant en détail les quatre liens du fichier Plus_Haut.html comme ci-après :

1°) - Le premier, Plus Haut, permet de remonter d'un cran dans la hiérarchie des zones. En effet, il remplace, grâce à l'attribut TARGET="_parent", un document composé de deux frames (Descendre.html ou A_Droite.html ou encore celui de A_Gauche.html par un document classique (Plus_Bas.html) ;

2°) - Le deuxième, Au Sommet, permet d'afficher le document Plus_Bas.html, en occupant tout l'espace de la fenêtre du browser (TARGET="_top"). On retombe ainsi dans un affichage classique, sans frame ;

3°) - Le troisième, Zone Verticale, permet de remplacer le document Descendre.html par le document A_Droite.html (toujours à l'aide de l'attribut TARGET="_parent"). Les deux documents ayant le même nombre de frames, la hiérarchie des frames n'est pas modifiée. Cela a juste pour effet de transformer la séparation horiziontale de la frame en une séparation verticale.

4°) - Le dernier, Zone Horizontale, permet de remplacer le document Descendre.html par le document A_Gauche.html (toujours à l'aide de l'attribut TARGET="_parent"). Les deux documents ayant le même nombre de frames, la hiérarchie des frames n'est pas modifiée. Cela a juste pour effet de transformer la séparation verticale de la frame en une séparation horizontale.

Voici le code correspondant du document Plus_Haut.html :

<HTML>

           <HEAD>

               <TITLE> PLUS_HAUT </TITLE>

           </HEAD>

          <BODY BGCOLOR="#292929" LINK="#FF0000" ALINK="#00FFFF" VLINK="#FF40FF"> <BR>

          <H2> <center> <font color="#FFFFFF"> "PLUS_HAUT.HTML" &nbsp;&nbsp;&nbsp; <a href="http://www.electronique-et-informatique.fr/Electronique-et-Informatique/HTML_et_Programmes/Sommaire_HTML_Programmes.html" TARGET="_TOP">Retour au Sommaire HTML</a> </font> </center> </H2>

          <p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <font face="Arial" size="4" color="#FFFFFF"> <a href="Plus_Bas.html" TARGET="_parent"> Plus Haut</a> &nbsp; (<I>_parent</I>) </font> </p> <BR>

          <p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <font face="Arial" size="4" color="#FFFFFF"> <a href="Plus_Bas.html" TARGET="_top"> Au Sommet</a> &nbsp; (<I>_top</I>) </font> </p> <BR>

          <p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <font face="Arial" size="4"> <a href="A_Droite.html" TARGET="_parent"> Zone Verticale</a> </font> </p> <BR>

          <p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <font face="Arial" size="4"> <a href="A_Gauche.html" TARGET="_parent"> Zone Horizontale</a> </font> </p>

          </BODY>

</HTML>

Voici quelques enchaînements obtenus à partir de cet exemple. Les flèches indiquent l'effet d'un clic sur un lien hypertexte. Pour plus de lisibilité, toutes les possibilités n'apparaissent pas sur le schéma ci-dessous :

Les frames et JavaScript :

La frame dispose des mêmes caractéristiques que l'objet window que l'on verra par la suite de nos leçons (la Classe Window).

Exemple : Choisir dans quelle frame l'image apparaîtra

L'exemple suivant montre comment on change l'image d'un point à l'autre, en cliquant sur Haut ou sur Bas, on change le TARGET d'un lien (ici une frame). Lorsque l'on effectue ce choix, rien ne se passe dans les fenêtres ; c'est seulement lorsque l'on clique sur l'image que celle-ci apparaît dans la zone choisie.

Le fichier INDEX.HTML (découpage du browser, fichier appelé que l'on cliquera sur ce dernier) :

Le menu est chargé dans la frame de gauche (Frame_Menu) et des fichiers vides sont chargés dans les deux autres frames (Frame_Haut et Frame_Bas) dont nous évoquerons les codes HTML ci-après ainsi que leurs fonctions :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6]. Nous allons continuer à examiner cet exemple :

Fichier INDEX.HTML, voici le code suivant :

<HTML>

           <HEAD>

               <TITLE> D&eacute;placement d'une Image </TITLE>

           </HEAD>

           <!-- Si une frame n'est pas charg&eacute;e avec un fichier,

il semble que le nommage de la frame ne se fasse pas, car elle ne peut pas &ecirc;tre adress&eacute;e.

En cons&eacute;quence m&ecirc;me, si la frame doit &ecirc;tre vide &agrave; l'origine, il est n&eacute;cessaire de la charger avec un document vide (Vide.html) -->

                    <FRAMESET COLS = " *, 2 * ">

                    <FRAME NAME = "Frame_Menu" SRC = "Menu.html">

                    <FRAMESET ROWS = " *, * ">

                    <FRAME NAME = "Frame_Haut" SRC = "Vide.html">

                    <FRAME NAME = "Frame_Bas" SRC = "Vide.html">

                    </FRAMESET>

                    </FRAMESET>

</HTML>

Le fichier MENU.HTML (création du menu, appelé par INDEX.HTML) :

<HTML>

           <HEAD>

           <!-- Cet exemple montre :

           1 - l'adressage des liens d'un document, en tableau :

                         links[0] = Haut

                         links[1] = Bas

                         links[2] = L'image

           2 - La possibilit&eacute; de changer le TARGET D'UN LIEN :

                         a - Si on clique sur l'affichage sans avoir cliqu&eacute; sur le lien hypertexte Haut

                               ou sur le lien Bas de l'Image, elle remplace le MENU.

                         b - Si on clique pr&eacute;alablement sur le lien hypertexte Haut de l'Image, elle vient

                               dans la frame du Haut &agrave; droite.

                         c - Si on clique pr&eacute;alablement sur le lien hypertexte Bas de l'Image, elle vient

                               dans la frame du Bas &agrave; droite.

           3 - L'adressage des frames -->

               <TITLE> MENU </TITLE>

                        <SCRIPT>

                             function ChangeTarget (NewTarget) {

                                 document.links[2].target=NewTarget;

                        }

                        </SCRIPT>

           </HEAD>

          <BODY BGCOLOR="#292929" LINK="#FF0000" ALINK="#00FFFF" VLINK="#FF40FF"> <BR> <BR> <BR>

          <CENTER> <font face="Arial" size="5" color="#FFFFFF"> <i> O&ugrave; voulez-vous mettre l'image &nbsp; ? </i> <p> <BR>

          En <a href=javaScript:ChangeTarget('Frame_Haut')> Haut de la Frame</a> ou <BR> <BR>

          Vers le <a href=javaScript:ChangeTarget('Frame_Bas')> Bas</a> <p> <BR> </font>

          <font face="Arial" size="7"> <i> <a href="Image.html" target=""> l'image</a> </i> </font> <BR> <BR> <BR> </p>

          <p> <HR> <BR> <BR> <font face="Arial" size="4"> <a href="Index.html" target="_parent"> [Recommencer]</font></a> </p>

          </CENTER>

          </BODY>

</HTML>

Le fichier IMAGE.HTML (appelé lorsque l'on clique sur " l'image ") :

<HTML>

           <HEAD>

               <TITLE> IMAGE </TITLE>

           </HEAD>

               <BR> <BR> <CENTER>

          <BODY BGCOLOR="#454545">

          <a href="Sommaire_HTML_Programmes.html" target="_top"> <font size="5" color="#FFFFFF"> [Retour au Sommaire HTML]</font></a> <BR> <BR>

          <a href="Index.html" target="_parent"> <font size="5" color="#FFFFFF"> [Revenir en arri&egrave;re]</font></a> <BR> <BR> <BR>

          <img border="0" width="120" height="120" src="images/Globe.gif"> <BR> <BR> <BR>

          <img boder="0" src="images/W.gif" width="105" height="86">

                </CENTER>

          </BODY>

</HTML>

Le fichier VIDE.HTML (appelé par INDEX.HTML) :

<HTML>

           <HEAD>

               <TITLE> DOCUMENT VIDE </TITLE>

           </HEAD>

          <BODY>

          <!-- Si une frame n'est pas charg&eacute;e avec un fichier,

          il semble que le nommage de la frame ne se fasse pas,

          car elle ne peut pas &ecirc;tre adressée -->

          </BODY>

</HTML>

Nous terminons ainsi les exemples des frames, nous allons résumer cette leçon.

Résumé :

Le découpage d'une fenêtre, en frames est réalisé à l'aide d'un document HTML spécial construit à partir de trois nouvelles balises.

<FRAMESET> . . . </FRAMESET> va permettre de préciser la géométrie des différentes frames. Il s'agit en quelque sorte d'une balise de déclaration. Elle possède deux attributs :

  • ROWS="hauteur_1, hauteur_2, ... hauteur_N" définit la hauteur des différentes frames en cas de découpage horizontal ;

  • COLS="largeur_1, largeur_2, ... largeur_N" définit la largeur des différentes frames en cas de découpage vertical.

<FRAME> est la balise de définition des frames déclarées à l'aide d'une balise <FRAMESET>. Elle possède six attributs :

  • SRC="URL" indique le document à afficher dans la frame ;

  • NAME="nom" indique le nom de la frame de telle sorte que cette frame puisse être utilisée comme cible d'un lien hypertexte ;

  • MARGINWIDTH="n" définit l'espace entre le document et les frontières verticales de la frame ;

  • MARGINHEIGHT="n" définit l'espace entre le document et les frontières horizontales de la frame ;

  • SCROLLING="yes/no/auto" indique si la frame doit ou non posséder une barre de défilement ;

  • NORESIZE indique qu'il est impossible à l'utilisateur de redimensionner la frame.

<NOFRAMES> . . . </NOFRAMES> est utilisé pour indiquer le texte que doivent afficher les browsers incapables de gérer les frames.

Enfin, un nouvel attribut a été créé de façon à pouvoir indiquer dans quelle frame doit être affiché le document associé à un lien hypertexte :

  • TARGET="nom_de_la_frame"

Ceci donnera par exemple :

<A HREF="URL" TARGET="nom_de_la_frame"> . . . </A>

<FORM ACTION="URL" TARGET="nom_de_la_frame"> . . . </FORM>

<AREA HREF=". . .">

Fin de cette treizième leçon, la prochaine sera consacrée aux Méta-informations concernant le langage HTML.


Les Méta-Informations HTML

Les Méta-Informations HTML :

La balise que nous allons étudier n'a d'autre but que de fournir des informations sur le document HTML. Ces informations ne sont pas visibles à l'écran et par conséquent ne sont pas destinées aux Internautes. Ce sont des informations sur le contenu de la page, prévues pour être processées par des programmes d'analyse automatique des documents. Par exemple, les robots analysent le réseau Internet et tentent d'indexer les pages Web afin de créer des répertoires. On utilise ensuite des moteurs de recherche qui, à partir d'un mot clé, proposent l'URL de tous les documents contenant ce mot clé. On conçoit aisément qu'une indexation automatique de tous les mots d'un document conduit à deux difficultés : le volume d'informations à stocker est très important et la pertinence des résultats de recherche n'est pas optimale.

<META> :

Cette balise se place dans le document ou page HTML, dans la zone d'en-tête situé entre les balises <HEAD> et </HEAD>. Si le robot d'indexation trouve des informations suffisantes dans les balises méta, il n'indexera pas tous les mots du document. Les mots clés ne seront que ceux qui auront été indiqués par l'auteur de la page.

Dans le cas général, le couple d'attributs NAME et CONTENT va permettre d'associer une valeur à un mot-clé.

<META NAME="mot_clef" CONTENT="valeur_attribuee_au_mot_clef">

L'attribut NAME sera remplacé par HTTP-EQUIV si la méta-information requiert une réponse du serveur.

<META HTTP-EQUIV="mot_clef" CONTENT="valeur_attribuee_au_mot_clef">

L'attribut NAME :

Il permet de spécifier un mot-clé indiquant quelle information donne la balise, on trouve parmi ces mots-clés :

  • AUTHOR, qui permet d'indiquer l'auteur ou les auteurs du document.

  • KEYWORDS, qui permet de donner des mots-clés sur le contenu du document.

  • DESCRIPTION, qui permet de donner une courte description de la page ou du site.

L'attribut CONTENT :

Il permet d'associer une valeur au mot-clé.

Exemples d'utilisation :

<meta name="author" content="Jean-Pierre">

<meta name="keywords" content="Condensateurs, résistances, transistors>

<meta name="description" content="Leçons Electroniques Fondamentales, Leçons Electroniques Digitales>

L'attribut HTTP-EQUIV :

Il s'emploie à la place de l'attribut NAME. Il indique au serveur qu'il doit inclure dans la zone d'en-tête de sa réponse les informations qu'il trouve dans les balises méta. Ainsi, si l'on a codé une balise de la façon suivante :

<META HTTP-EQUIV="Expires" CONTENT="Mardi, 24 Juin 2016 23:10:30">

Le serveur répondra ainsi à l'en-tête du document demandé :

Expires: Mardi, 24 Juin 2016 23:10:30.

Le client-pull :

A l'aide de la balise <META> et de l'attribut HTTP-EQUIV, auquel on associe le mot-clé REFRESH, on peut décrire deux utilisations possibles de client-pull.

Premier cas : On se propose de réactualiser, à intervalle régulier, le contenu d'une page. Cela peut être utile lorsque l'on a une caméra de télésurveillance qui diffuse une image sur le Web.

Dans l'exemple suivant, le browser charge la page puis, conformément à ce qu'il trouve dans la balise <META>, il redemande la page toutes les 5 secondes dans le cas de notre exemple.

Voici le code HTML de la première page intitulée "Apercu_1_Camera_Meta_Refresh.html"

Inutile de vous dire que vous pouvez changer le titre de la page ou son URL.

<HTML>

<HEAD>

<TITLE> T&eacute;l&eacute;surveillance </TITLE>

<META http-equiv="refresh" content="5; URL=Apercu_2_Camera_Meta_Refresh.html">

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<H2> Regardez bien l'image, la page se r&eacute;actualise toutes les 5 secondes ! </H2> <BR> <BR> <BR> <BR>

<img src="images/Camera.jpg"> <BR> <BR> <BR>

<H2> <a href="Sommaire_HTML_Programmes.php"> Retour au sommaire PHP</a> </H2>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Voici le code HTML de la deuxième page intitulée "Apercu_2_Camera_Meta_Refresh.html"

<HTML>

<HEAD>

<TITLE> T&eacute;l&eacute;surveillance </TITLE>

<META http-equiv="refresh" content="5; URL=Apercu_1_Camera_Meta_Refresh.html">

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<H2> Regardez bien l'image, la page se r&eacute;actualise toutes les 5 secondes ! </H2> <BR> <BR> <BR> <BR>

<img src="images/Camera_2.jpg"> <BR> <BR> <BR>

<H2> <a href="Sommaire_HTML_Programmes.php"> Retour au sommaire PHP</a> </H2>

</CENTER>

</BODY>

</HTML>

On est en droit de se demander comment l'image de la Camera.jpg. est mise à jour. On peut imaginer un dispositif selon lequel l'image d'une caméra est acquise par un micro-ordinateur équipé d'une carte d'acquisition vidéo ; cette image est traitée pour être enregistrée au format GIF ou JPEG puis être transférée sur le serveur.

Second cas : Au bout d'une durée déterminée, on veut changer automatiquement le document affiché. Cela sert, par exemple, si l'on change l'adresse d'une page ; sur l'ancienne adresse, on donne l'information concernant ce changement ; au bout de quelques secondes, on affiche la nouvelle page :

Voici le code HTML de la première page intitulée "Apercu_3_Nouvelle_Page_Meta_Refresh.html"

<HTML>

<HEAD>

<TITLE> Ancienne Adresse URL </TITLE>

<!-- Au bout de 10 secondes on ira rechercher automatiquement la nouvelle page -->

<META http-equiv="refresh" content="5; URL=Apercu_4_Nouvelle_Page_Meta_Refresh.html">

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<H2> La page se r&eacute;actualise toutes les 5 secondes pour aller rechercher la nouvelle Adresse URL ! </H2> <BR> <BR> <BR> <BR>

<img src="images/Un.gif"> <BR> <BR> <BR>

<H2> <a href="Sommaire_HTML_Programmes.php"> Retour au sommaire PHP</a> </H2>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Voici le code HTML de la deuxième page intitulée "Apercu_4_Nouvelle_Page_Meta_Refresh.html"

<HTML>

<HEAD>

<TITLE> Nouvelle Adresse URL </TITLE>

<!-- Au bout de 10 secondes, on ira rechercher automatiquement le sommaire PHP -->

<META http-equiv="refresh" content="5; URL=Sommaire_HTML_Programmes.php">

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<H2> La page se r&eacute;actualise toutes les 5 secondes pour aller vers le sommaire HTML, attendez SVP ! </H2> <BR> <BR> <BR> <BR>

<img src="images/Deux.gif"> <BR> <BR> <BR>

<H2> <a href="Sommaire_HTML_Programmes.html"> Retour au sommaire HTML</a> </H2>

</CENTER>

</BODY>

</HTML>

Voici le même aperçu de la deuxième page, en cliquant ici. [Exemple 3].

Fin de cette quatorzième leçon, la prochaine sera consacrée à la programmation concernant le langage HTML.


La programmation et les Limites HTML

La Programmation et les Limites HTML :

Cette leçon constitue une introduction à la programmation d'applications sur les serveurs Web. Destiné à mettre en évidence les limites du langage, il montrera comment la programmation permet de s'en affranchir.

Pour illustrer cette leçon, nous travaillerons sur un exemple concret emprunté au mode de présentation des données que l'on trouve sur certains micro-odinateurs. Dans le Finder (chercheur ou recherche) de certains ordinateurs, il est possible de présenter le contenu d'un répertoire de plusieurs façons. La figure ci-dessous montre ainsi deux dossiers présentés différemment :

L'image de gauche présente le contenu du répertoire à l'aide des icônes, tandis que celle de droite, les différents éléments du dossier sont présentés dans une liste précédée d'une ou deux icônes. La première icône (un petit triangle) est présente chaque fois que l'élément est un répertoire ou une liste. Si l'on clique sur ce petit triangle, il pivote vers le bas, tandis que le contenu du répertoire ou d'une liste est développé légèrement sur la droite pour indiquer la hiérarchie des répertoires.

Dans la figure ci-dessus, on a cliqué sur le triangle du dossier "channel" ou sur "rss version 2.0" et est apparu le contenu de cette liste. Si l'on clique à nouveau sur ce petit triangle, on "referme" le répertoire ou la liste et on revient à la situation précédente.

Est-il possible de concevoir un modèle analogue avec le langage HTML ? Avant de répondre à cette question, essayons de résoudre l'exercice suivant :

Prenons le menu d'un restaurant comportant trois rubriques :

  • Les entrées

  • Les viandes

  • Les desserts

Chacune de ces rubriques, contient les plats de sa catégorie.

Pour les entrées :

  • Salade

  • Charcuterie

  • Melon

Pour les viandes :

  • Entrecôte

  • Poulet

  • Escalope

Pour les desserts :

  • Crème renversée

  • Glaces

  • Fruits

On veut présenter une page HTML dont le mode de fonctionnement sera identique à celui que nous avons décrit pour les répertoires ou listes du Finder des micro-ordinateurs :

La première page HTML affichera simplement trois lignes comportant les trois rubriques principales.

Cliquer sur le titre d'une rubrique lorsque son contenu n'est pas affiché, provoque l'affichage, sous ce titre, des plats composants cette rubrique (mode ouverture d'une rubrique ou mode déplié).

Cliquer sur le titre d'une rubrique lorsque son contenu est affiché fait disparaître les plats pour ne laisser que le titre (mode fermeture d'une rubrique ou mode replié).

Dans les deux cas, (fermer ou ouvrir une rubrique), l'état d'affichage des autres rubriques est sauvegardé.

On ne se préoccupera pas du petit triangle qui tourne. ce n'est qu'un aspect graphique simple à maîtriser.

Avec trois catégories, nous aurons à décrire 23 situations correspondant aux affichages souhaités. Le tableau de la figure 1, résume toutes les combinaisons possibles d'affichage des différentes rubriques. Le signe [image] indique que le contenu de la rubrique est affiché, le signe [image] indique que seul est affiché le nom de la rubrique. Chaque colonne correspond à un fichier :

Le fichier F1 (F1.html) :

Il comporte simplement les trois titres de rubriques "Entrées, Viandes et Desserts" puisque toutes les cases de la colonne F1 ont la valeur [image] .

Les pointeurs sur les titres de rubriques prévoient les états futurs :

Entrées est un pointeur sur F5 car, lorsqu'on clique sur Entrées, on doit afficher la liste des entrées et l'intersection entre la ligne "Entrées" et la colonne F5 donne bien la valeur [image] .

F5 satisfait aussi la condition de sauvegarde puisque l'on part de F1 où Viandes et Desserts n'étaient pas affichés, pour arriver à un état où ils ne sont toujours pas affichés.

Viandes est un pointeur vers F3 car, lorsqu'on clique sur Viandes, la liste des viandes doit s'afficher et l'intersection entre la ligne "Viandes" et la colonne F3 donne bien la valeur [image] .

F3 satisfait aussi la condition de sauvegarde puisque l'on part de F1 où les Entrées et Desserts n'étaient pas affichés, pour arriver à un état où ils ne sont toujours pas affichés.

Desserts est un pointeur vers F2 car, lorsqu'on clique sur Desserts, on doit afficher la liste des desserts et l'intersection entre la ligne "Desserts" et la colonne F2 donne bien la valeur [image] .

F2 satisfait aussi la condition de sauvegarde puisque l'on part de F1 où les Entrées et Viandes n'étaient pas affichés, pour arriver à un état où elles ne sont toujours pas affichés.

Les trois lignes de code concernant les liens hypertexte seront de couleur bleue claire, afin de pouvoir les différencier de certains codes de la page HTML du fichier F1.html s'écriront donc :

<HTML>

<HEAD>

<TITLE> Fichier 1 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

<SCRIPT LANGUAGE = "JavaScript">

function Visibilitee ( Masquer_Demasquer )

{

var targetElement; targetElement = document.getElementById ( Masquer_Demasquer ) ;

if ( targetElement.style.display == "none" )

{

targetElement.style.display = "" ;

}

else

{ targetElement.style.display = "none" ;

}

}

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR>

<H1> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="" onclick="javascript:Visibilitee('id_div_1'); return false;" >Menu Restaurant</a> </H1>

<div id="id_div_1" style="display:none;">

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F5.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F3.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F2.html">Desserts</a> </H2>

</div>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1]

Le fichier F2 (F2.html) :

Son état présent, affiche les titres de la rubrique Entrées, Viandes, le titre de la rubrique Desserts "suivi" de la liste des desserts. Les pointeurs affectés aux titres de la rubrique doivent prévoir l'état futur. Le même raisonnement que précédemment nous conduit ainsi à dire que :

Entrées pointe maintenant vers F6 (que l'on notera à l'avenir E'F6).

Viandes pointe vers F4 (que l'on notera V'F4).

Desserts pointe vers F1 (que l'on notera D+' F1, le signe (+) en exposant indiquant l'affichage du contenu de la rubrique).

Le fichier F2.html contiendra les lignes suivantes (toujours en couleur bleue claire) :

<HTML>

<HEAD>

<TITLE> Fichier 2 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F6.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F4.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F1.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Cr&egrave;me renvers&eacute;e </li>

<li> Glaces </li>

<li> Fruits </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2]

On applique la même méthode pour les fichiers F3 à F6. Donnons simplement les relations pour ces fichiers.

F3 = E'F7, V+'F1, D'F4

F4 = E'F8, V+'F2, D+'F3

F5 = E+'F1, V'F7, D'F6

F6 = E+'F2, V'F8, D+'F5

F7 = E+'F3, V+'F5, D'F8

F8 = E+'F4, V+'F6, D+'F7

Une fois les huit fichiers ainsi décrits, on peut procéder aux essais ... Si l'on ne s'est pas trompé, tout marchera correctement ; sinon, il restera à rééditer les huit fichiers pour vérification. Toutefois, nous allons simplifier votre tâche, en effectuant le décodage que nous avions évoqué ci-dessus, et que, nous allons éditer les 6 autres fichiers HTML.

Entrées pointe maintenant vers F7 (que l'on notera E'F7).

Viandes pointe vers F1 (que l'on notera V+'F1).

Desserts pointe vers F4 (que l'on notera D'F4,

Le fichier F3 (F3.html) :

<HTML>

<HEAD>

<TITLE> Fichier 3 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F7.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F1.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F4.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Entrec&ocirc;te </li>

<li> Poulet </li>

<li> Escalope </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3]

Entrées pointe maintenant vers F8 (que l'on notera E'F8).

Viandes pointe vers F2 (que l'on notera V+'F2).

Desserts pointe vers F3 (que l'on notera D+'F3,

Le fichier F4 (F4.html) :

<HTML>

<HEAD>

<TITLE> Fichier 4 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F8.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F2.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F3.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Entrec&ocirc;te </li>

<li> Poulet </li>

<li> Escalope </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Cr&egrave;me renvers&eacute;e </li>

<li> Glaces </li>

<li> Fruits </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4]

Entrées pointe maintenant vers F1 (que l'on notera E+'F1).

Viandes pointe vers F7 (que l'on notera V'F7).

Desserts pointe vers F6 (que l'on notera D'F6.

Le fichier F5 (F5.html) :

<HTML>

<HEAD>

<TITLE> Fichier 5 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F1.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F7.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F6.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Salade </li>

<li> Charcuterie </li>

<li> Melon </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5]

Entrées pointe maintenant vers F2 (que l'on notera E+'F2).

Viandes pointe vers F8 (que l'on notera V'F8).

Desserts pointe vers F5 (que l'on notera D+'F5.

Le fichier F6 (F6.html) :

<HTML>

<HEAD>

<TITLE> Fichier 6 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F2.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F8.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F5.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Salade </li>

<li> Charcuterie </li>

<li> Melon </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Cr&egrave;me renvers&eacute;e </li>

<li> Glaces </li>

<li> Fruits </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6]

Entrées pointe maintenant vers F3 (que l'on notera E+'F3).

Viandes pointe vers F5 (que l'on notera V+'F5).

Desserts pointe vers F8 (que l'on notera D'F8.

Le fichier F7 (F7.html) :

<HTML>

<HEAD>

<TITLE> Fichier 7 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F3.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F5.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F8.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Salade </li>

<li> Charcuterie </li>

<li> Melon </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Entrec&ocirc;te </li>

<li> Poulet </li>

<li> Escalope </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7]

Entrées pointe maintenant vers F4 (que l'on notera E+'F4).

Viandes pointe vers F6 (que l'on notera V+'F6).

Desserts pointe vers F7 (que l'on notera D+'F7.

Le fichier F8 (F8.html) :

<HTML>

<HEAD>

<TITLE> Fichier 8 </TITLE>

<STYLE TYPE="text/css">

<!-- A { color:#993300; text-decoration:none; } A:hover { color:#FF0000;text-decoration:underline; } -->

</STYLE>

</HEAD>

<BODY BGCOLOR="#DADADA" LINK="#FF0000" ALINK="#FF00FF" VLINK="#000000"> <BR>

<CENTER> <H1> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H1> </CENTER> <BR> <BR> <BR>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F4.html">Entr&eacute;es</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F6.html">Viandes</a> </H2>

<H2> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img src="images/Petite_Main.gif"> &nbsp; <a href="F7.html">Desserts</a> </H2>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Salade </li>

<li> Charcuterie </li>

<li> Melon </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Entrec&ocirc;te </li>

<li> Poulet </li>

<li> Escalope </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

<ul> <H2>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<ul>

<li> Cr&egrave;me renvers&eacute;e </li>

<li> Glaces </li>

<li> Fruits </li> </H2>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</ul>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8]

Imaginons maintenant que nous voulions compléter ce menu, par une catégorie "poissons", une catégorie "fromage" et une catégorie "pizza". On passe ainsi de trois à six catégories, et le nombre de fichiers à éditer est de 26 soit 64 fichiers !! Ce nombre est suffisamment grand et la méthode que nous venons de décrire est suffisamment fastidieuse pour ne pas se lancer dans un tel travail.

Ce petit exercice avait simplement pour but de montrer les limites du langage. Les présentations de données telles qu'on les voit sur les écrans des ordinateurs ne sont pas toujours réalisables facilement en HTML.

Le recours à la programmation permet de repousser certaines limites. Il permet de résoudre des listes de ce type sans limite du nombre de catégories.

Nous verrons plus tard au cours de nos leçons qu'il existe des listes repliables et dépliages sans pour autant d'avoir autant de pages HTML comme l'exercice ci-dessus.

Et enfin, pour terminer cette leçon, nous allons faire un bref résumé :

Nous résumons cette leçon ci-après :

Cette leçon est avant tout un exercice montrant les limites du langage HTML que nous avions déjà évoqué.

En résumé, rappelons que le niveau actuel d'HTML ne permet pas tous les types de représentation de l'information que l'on a l'habitude de trouver dans les applications d'informatique ou de micro-informatique.

L'interface de programmation peut cependant apporter une réponse très favorable à ces limitations dans de nombreux cas.

Fin de cette quinzième leçon, la prochaine sera consacrée aux formulaires concernant le langage HTML.


Les Formulaires

Les Formulaires :

Jusqu'à présent, nous avons appris à réaliser des pages HTML fonctionnant sur le modèle suivant :

Un auteur peut créer des documents ou pages HTML et de les mettre à disposition sur un serveur Web.

Le lecteur utilise un browser pour aller consulter ces pages, en cliquant sur des liens. Il peut se promener ainsi à son gré dans les pages mais n'intervient jamais.

Il s'agit d'un mode de consultation où le seul choix possible concerne le cheminement parmi les pages. A aucun moment, il n'y a d'interactivité réelle entre le lecteur et le système qui fournit les documents.

Imaginons que nous voulions réaliser sur un serveur Web un service permettant de commander une documentation. Il faudra proposer sur la page HTML, une liste des documentations disponibles, puis de collecter le nom et l'adresse du demandeur afin de pouvoir lui envoyer par la suite.

On peut aussi concevoir une recherche dans une base de données, un dictionnaire par exemple : le lecteur tape dans la page HTML le mot à rechercher, puis reçoit dans la page suivante la définition du mot.

Les formulaires ou forms sont le moyen offert par le langage HTML pour générer à l'écran des zones de dialogue avec le lecteur.

Comme dans un formulaire papier, on pourra réaliser des zones dans lesquelles on entrera un texte, des cases à cocher, des listes de choix, et bien d'autres encore ...

Un formulaire n'est qu'une interface de saisie ; il nécessite des éléments pour traiter l'information qui y est collectée. Avec l'arrivée des scripts exécutés par le poste client, la gestion d'une interface de saisie va devenir beaucoup plus efficace, beaucoup plus dynamique. Bien sûr, il existe des formulaires en langage PHP, que l'on expliquera lorsqu'on sera arrivé à ce langage un peu plus complexe que l'HTML, pour l'instant, restons simple et, nous devons terminer ce langage que nous avions commencé !

Quel est le principe du formulaire ?

A l'aide des balises HTML, on décrit les zones dans lesquelles l'utilisateur va remplir son formulaire. Chacune de ces zones sera identifiée par un nom symbolique. Lorsque le formulaire est envoyé au programme d'exploitation, celui-ci reçoit l'identificateur de chaque zone et la valeur sera saisie.

De plus, on peut associer à la plupart des balises un traitement spécifique, exécuté localement par le browser, lorsqu'un événement survient sur l'élément décrit par cette balise. Ce traitement est décrit par un petit programme JavaScript inséré dans le fichier HTML.

Par exemple, on décrit un champ dans lequel l'utilisateur du formulaire tapera son année de naissance ; on attribue à cette zone le nom symbolique de "AnneeNaissance". L'utilisateur tape dans ce champ 1985. Le script s'assure que la donnée est bien numérique, et si tel est le cas, il l'envoie au programme CGI (Common Gateway Interface) qui reçoit : AnneeNaissance=1985.

Le programme CGI chargé du traitement final du formulaire peut être écrit dans le langage préféré du programmeur. Par exemple, Langage C, Fortran, Perl, C-shell, Schell convient pour des serveurs installés sur des machines Unix ou VMS que l'on verra plus tard au cours de nos leçons. Pour l'instant, restons simple.

A quel moment le formulaire est-il transmis au script ?

A la fin de la saisie, dont tous les champs ne sont d'ailleurs pas nécessairement renseignés, est déclenchée lorsque l'on clique sur un bouton spécial appelé "bouton de soumission" ou sur un lien hypertexte prévu à cet effet.

Si un script (de validation des données par exemple) est associé à la soumission du formulaire, il est appelé en premier. En revanche, si le programmeur a correctement conçu sa fonction, il aura utilisé un code de retour permettant de différer l'envoi tant que les données ne sont pas correctes. Bien sûr, il alertera l'utilisateur par un message spécial indiquant que la saisie est erronée.

Enfin, quand le poste client (le browser) décidera, à l'aide de ces fonctions JavaScript que les données sont valides, il les expédiera vers le serveur pour le traitement ultime.

Avant de commencer la description des balises, dressons l'inventaire des éléments à notre disposition pour créer ces formulaires.

Le look de ces éléments présentés à la figure 1, est celui d'un environnement Motif ; sur un Macintosh ou sur un PC, cette présentation diffère un peu mais la fonctionnalité reste la même.

On définit arbitrairement trois catégories d'éléments :

Une catégorie INPUT s'appliquant à divers types d'entrées (champ de saisie de texte et divers types de boutons) ;

Une catégorie SELECT s'appliquant aux listes (menus déroulants, listes à ascenseurs) ;

Une catégorie TEXTAREA s'appliquant à une zone de saisie de texte libre.

Description des balises de formulaire et des événements JavaScript associés :

Nous allons maintenant décrire les balises permettant de générer un formulaire. Elles permettent de fabriquer une interface de saisie, mais à ce niveau, on est pas encore réellement dans la programmation ; que l'on verra à l'étude au cours de la prochaine leçon, essentiellement consacré à la programmation CGI. On procède cependant au choix du nom des variables qui identifieront les éléments du formulaire, et on indique simplement le nom du script devant exploiter les données de ce formulaire. On décide aussi du traitement à associer aux événements. Il appartient ensuite au programmeur de coder les scripts. Ces deux tâches, fabrication de l'interface et du codage des scripts, peuvent très bien être réalisées par deux personnes collaborant sur la même application.

<FORM>

La balise <FORM> débute la description d'un formulaire. Entre la balise de début <FORM> et la balise de fin </FORM> se situeront toutes les balises générant les divers boutons, cases à cocher, entrées de texte, etc. Mais aussi du texte HTML standard permettant "d'habiller" et d'auto-documenter le formulaire.

Cette balise possède plusieurs attributs :

L'attribut METHOD :

Il s'adresse au programmeur qui va coder le script CGI. On en trouvera une description complète dans la prochaine leçon de la Programmation CGI. Pour l'instant, disons simplement pour le moment que cet attribut peut prendre deux valeurs, GET et POST, indiquant la méthode de transfert des données acquises vers le script CGI.

L'attribut ACTION :

Sa fonction est d'indiquer l'action à entreprendre (le script à exécuter) lorsque l'on clique sur le bouton de soumission. "Action" définit donc l'URL du script permettant d'exploiter le formulaire. Attention : On parle ici de script CGI (s'exécutant sur le serveur) et non de script JavaScript (exécuté sur le poste client).

L'attribut NAME :

Il possède deux fonctions particulières :

Dans un même document peuvent résider plusieurs formulaires. L'attribut NAME permet de définir, lors de l'envoi des données vers le script CGI, le formulaire qui les expédie.

Dans la représentation des éléments du formulaire, en objet JavaScript, il permet le nommage du formulaire. Dans la hiérarchie des objets du browser, le formulaire identifié par son nom (NAME=nom) pourra être référencé par les fonctions JavaScript.

L'attribut TARGET :

L'exécution d'un script se traduit toujours par un résultat qui est une nouvelle page HTML ! Cette nouvelle page peut venir remplacer la page qui contenait le formulaire, ou s'inscrire dans une frame ou dans une autre fenêtre. En l'absence de l'attribut TARGET, on remplace la page courante, en revanche, l'attribut TARGET permet d'indiquer la frame ou la fenêtre dans laquelle s'affiche la nouvelle page.

Les propriétés de l'objet FORM :

Elles sont en nombre de cinq :

ACTION permet de lire ou de modifier l'action (c'est-à-dire l'URL ou le peudo-protocole) associé au formulaire.

Dans l'exemple ci-dessous, l'instruction HTML <FORM> programme un appel à l'annuaire général ; l'exécution de l'instruction JavaScript modifie le formulaire qui appelle maintenant l'annuaire des services.

<form name="Formules" action="/electronique-et-informatique/annuaireGeneral">

. . .

</form>

<script> document.Formules.action="/electronique-et-informatique/annuaireService"> </script>

METHOD permet de lire ou de modifier la méthode (GET ou POST) associée au formulaire.

TARGET permet de lire ou de modifier la cible dans laquelle va être envoyé le résultat provoqué par l'exécution du formulaire.

Dans l'exemple ci-dessous, telle qu'est programmée la balise HTML, le résultat du formulaire s'afficherait à la place du formulaire (pas de target spécifié). L'instruction JavaScript modifie ce comportement et envoie le résultat dans une nouvelle fenêtre.

<form name="Formules" action="/electronique-et-informatique/annuaireGeneral">

. . .

</form>

<script> document.Formules.target="NouvelleFenetre" </script>

ENCTYPE permet de connaître ou de modifier l'encodage (le content-type Mine) des données transmises vers le formulaire.

ELEMENTS permet d'analyser les objets composant le formulaire :

ELEMENTS.LENGTH donne le nombre d'objets composant le formulaire,

ELEMENTS[n].NAME donne le nom associé à l'objet de rang n,

ELEMENTS[n].VALUE ou ELEMENT.NOM_DE_L'OBJET.VALUE donne sa valeur.

La méthode de l'objet FORM :

SUBMIT permet de déclencher, exactement comme si l'on cliquait sur le bouton submit, l'envoie du formulaire.

Dans l'exemple ci-dessous, on soumet le formulaire à travers un lien hypertexte.

<a href=javascript:document.mecaniqueGenerale.submit()>Annuaire</a>

L'événement JavaScript associé à l'objet FORM :

L'événement onSubmit permet de spécifier l'exécution sur le poste client (donc par le browser) d'une fonction JavaScript. Cette fonction (ce programme) s'exécute donc au moment où l'on clique sur le bouton submit. Elle servira par exemple à tester si une donnée du formulaire considérée comme obligatoire a bien été saisie. Cette fonction pourra (si le programmeur le code) renvoyer un booléen (true ou false) qui permettra, selon la formulation utilisée dans la balise, de bloquer l'exécution du script CGI tant que le booléen n'a pas la valeur true.

La syntaxe générale d'ouverture d'un formulaire est donc :

<FORM NAME=nom_du_formulaire

METHOD=type_de_methode

ACTION=URL_du_script

TARGET=nom_de_la_frame

onSubmit=fonction>

Cette dernière ligne peut être formulée différemment :

onSubmit=return fonction>

Dans ce type de formulation, si la fonction renvoie false, le script CGI spécifié par l'attribut ACTION n'est pas exécuté. Il est nécessaire alors de prévenir l'utilisateur par une fenêtre d'alarme que sa saisie est incomplète et qu'il est invité à soumettre une nouvelle fois son formulaire après l'avoir complété.

Exemple :

<FORM METHOD="post" NAME="Formulaire_1" ACTION="/electronique-et-informatique/inscription" TARGET="recup" onSubmit="return VeriFiche()">

Exemple de formulaire générant un E-Mail avec sujet et pays :

L'exemple suivant montre comment fabriquer le sujet d'un E-Mail à partir d'un choix effectué dans une pop-liste. Le corps du Mail est ensuite obtenu à partir d'un texte saisi dans un textarea complété par les informations sur le client (browser) qui est utilisé pour saisir le Mail. Ces dernières informations sont stockées dans un champ hidden (voir le type HIDDEN plus loin de nos leçons, HIDDEN = Masquer) avant la transmission vers l'URL MAILTO.

Au moment de l'envoie du Mail, on génère de nouveau le texte saisi, en le complétant par un message de confirmation.

<HTML>

<HEAD>

<TITLE> Formulaire E-Mail </TITLE>

<SCRIPT>

function Envoyer() {

var Text =" ";

var Index = 0;

var Identif = "mon_Formulaire_Mail"

// Cr&eacute;ation du sujet du Mail qui contient l'identification (Identif)

// et l'option s&eacute;lect&eacute;e (probl&egrave;me, suggestion, commentaire)

with (window.document.Mail) {

i = elements["sujet"].length - 1;

for (; i >= 0; i--) {

if (elements["sujet"][i].selected == true) {

Index = i;

break;

}

}

// G&eacute;n&eacute;ration de l'action du formulaire mailto

action = 'mailto:daniel.robe@free.com?content-type = text/html&sujet=';

action += Identif + '(' + elements["sujet"][Index].value + ')';

}

// Cr&eacute;ation du corps Mail et r&eacute;cup&eacute;ration du type de browser utilis&eacute;

// par la personne qui &eacute;met le Mail

with (navigator) {

Text = appName + ' ' + appVersion + '\n';

Text += appCodeName + 'depuis' + userAgent + '\n';

}

with (window.document.Mail) {

// L'information sur le browser est stock&eacute;e dans un champ HIDDEN (browser)

elements["Browser"].value = Text;

// On r&eacute;cup&egrave;re le texte saisi + le message "message envoy&eacute;"

elements["Message"].value += '\n\n *** Message envoye *** \n\n';

}

return true;

}

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#C0C0C0">

<FORM

NAME ="Mail"

ACTION=""

METHOD="POST"

ENCTYPE="text/plain"

onSubmit="Envoyer()">

<CENTER>

<b> Sujet du Mail : </b> <BR>

<select name="sujet">

<option value="PROBLEME"> Probl&egrave;me

<option value="SUGGESTION"> Suggestion

<option value="COMMENTAIRE" selected> Commentaire

<option value="COMMERCIAL"> Commercial

<option value="PROBLEME TECHNIQUE"> Technique

<option value="GEOMETRIE"> G&eacute;om&eacute;trie

<option value="MECANIQUE GENERALE">M&eacute;canique G&eacute;n&eacute;rale

</select> <BR> <BR>

<b> Pays : </b> <BR>

<select name="Pays">

<option value="FRANCE"> France

<option value="CANADA"> Canada

<option value="ITALIE"> Italie

<option value="SUEDE"> Su&egrave;de

<option value="ALLEMAGNE"> Allemagne

<option value="AFRIQUE"> Afrique

<option value="NORVEGE"> Norv&egrave;ge

<option value="BELGIQUE"> Belgique

<option value="GRANDE BRETAGNE"> Angleterre

<option value="ESPAGNE" selected> Espagne

</select> <p> <HR>

<b> Message : </b> <BR>

<textarea name="Message" rows="15" cols="70" wrap> </textarea>

<input type="hidden" name="Browser"> <HR> <p>

<input type="submit" value="Envoyer le message">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<input type="reset" value="Initialiser le formulaire">

</CENTER>

</FORM

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

On remarquera dans cet exemple le calcul de l'action pour le formulaire "Mail".

On verra dans la prochaine leçon JavaScript with pour l'utilisation de cette instruction, y compris certains paramètres du formulaire pour bien comprendre le code de certaines fonctions sans oublier certains paramètres que l'on verra plus tard ...

Pour l'instant, nous terminons ce premier chapitre afin de ne pas encombrer cette page, et nous continuerons la suite de cette leçon concernant les formulaires.

Fin de ce premier chapitre, le prochain sera consacré "aux balises définissant les composants du formulaire", toujours dans le même domaine HTML.


Balises Définissant les Composants du Formulaire

Les Balises Définissant les Composants du Formulaire :

Les Balises Définissant les Composants du Formulaire :

Dans la hiérarchie des objets, toutes les balises qui vont être décrites jusqu'à la fin de cette leçon sont à considérer comme des propriétés de l'objet form.

<INPUT> ou <INPUT TYPE="TEXT"> :

Avec attribut (l'attribut implicite est du TYPE="text"), la balise <INPUT> définit une zone d'entrée de texte simple. Ainsi l'instruction est la suivante :

<INPUT NAME="prenom" align="absmiddle" TYPE="TEXT" STYLE="font-weight:bold; color:#000000; width:150px; height:20px; font-size:14px; background-color:#CCCCCC" value="Jean-Pierre"> ; (ne pas mettre l'accentuation dans les codes HTML ou PHP et autres langages, sinon, cela ne peut fonctionner).

Donnera l'affichage ci-après : dans lequel on peut saisir un text de longueur supérieure à la dimention de la case (scrolling horizontal).

Vous pouvez faire vos essais ci-après, en tapant du texte ou des chiffres :

L'attribut NAME :

Comme la balise <FORM>, permet une double identification :

Dans le script CGI, il permet de reconnaître la donnée et la valeur qui y a été saisie (prenom=Marianne par exemple).

Dans le script JavaScript, il permet d'accéder aux propriétés et aux méthodes de l'objet texte.

L'attribut SIZE :

<INPUT SIZE="10" NAME="prenom" align="absmiddle" TYPE="TEXT" STYLE="font-weight:bold; color:#000000; height:20px; font-size:14px; background-color:#CCCCCC" value="Jean-Pierre">

Cet attribut permet de fixer la longueur de la zone de texte (mesurée en caractères) comme ci-après :

L'attribut VALUE :

Cet attribut permet de préinscrire un texte dans le champ d'entrée des caractères. Cela sert par exemple à autodocumenter un formulaire ; dans la case où l'on attend le prénom d'un individu, on peut inscrire le texte suivant : "ici votre prénom". On pourrait aussi y inscrire la valeur la plus probable comme par exemple l'adresse d'un individu ; ce dernier conservera ce champ intact s'il n'a pas changé d'adresse.

<INPUT SIZE="50" NAME="adresse" value ="4, Rue Place de la République" align="absmiddle" TYPE="TEXT" STYLE="font-weight:bold; color:#000000; height:20px; font-size:14px; background-color:#CCCCCC">

Exemple :

Les propriétés de l'objet TEXT :

Les propriétés d'un objet permettent d'en connaître les caractéristiques, par exemple son nom ou la valeur qui y est stockée. Ainsi, si la balise <INPUT> s'inscrit dans un formulaire dont le nom est par exemple FormFichier, on accède depuis une fonction JavaScript aux propriétés suivantes (dans le cas où l'utilisateur a saisi "Patricia"). :

document.FormFichier[n] qui va renvoyer le prenom

document.FormFichier.prenom.name qui va renvoyer le prenom

document.FormFichier[n].value qui va renvoyer le prenom Patricia

document.FormFichier.prenom.value qui va renvoyer le prenom Patricia

document.FormFichier[n].type qui va renvoyer le text

document.FormFichier.prenom.type qui va renvoyer le text

Sachant que les composants d'un formulaire peuvent être considérés comme des éléments d'un tableau numérotés à partir de zéro [0], on peut accéder à un élément soit par son indice, soit par son nom.

L'objet TEXT possède ainsi quatre propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur saisie par l'utilisateur.

defaultValue retourne la valeur originale préinscrite dans le champ.

type retourne le type de l'objet (celui spécifié par l'attribut type dans la balise HTML, soit text dans le cas présent).

Les méthodes de l'objet TEXT :

La méthode d'un objet définit la fonction qu'on lui applique. Par exemple, si l'on souhaite choisir dans un formulaire, la première zone de saisie active, (zone dans laquelle "entrent" les caractères tapés au clavier), on programme une action particulière (la prise du focus) sur l'objet représentant cette zone de saisie.

Il existe trois méthodes pour l'objet INPUT :

focus permet de positionner le curseur de saisie dans le champ.

blur permet de forcer le curseur de saisie hors du champ.

select permet de sélectionner tout le texte saisi dans le champ.

Ainsi, dans l'exemple suivant, on sélectionne le champ prénom comme premier champ de saisie :

document.FormFichier.prenom.focus()

Le jeu de parenthèses est obligatoire lorsqu'on applique une méthode à un objet, car en réalité, on fait appel à une fonction (sans paramètres) intrinsèque à l'interpréteur JavaScript.

Les événements associés à l'objet TEXT :

Le traitement des événements (programmation événementielle) est la partie la plus intéressante du langage. La page s'animera dès l'intervention de l'utilisateur (l'événement) qui entraîne, en effet, un traitement particulier.

Au niveau de la balise HTML, le programmeur indique pour chaque type d'événements qu'il souhaite traiter, la fonction qu'il va effectuer (onEvenement=uneFonction(avecOuSansParametres)). Il doit ensuite coder cette fonction dans la zone des scripts (JavaScript).

Considérons la balise HTML suivante :

<INPUT NAME="revenu" onFocus="aideContexte('indiquer le montant sans les centimes')" onBlur="verificationNum(this.value)">

Le programmeur positionne une zone pour la saisie du montant des revenus. Par la fonction "aideContexte" associée à l'événement onFocus, il fait en sorte que, lorsque l'utilisateur clique dans la case de saisie, il reçoive automatiquement, dans une zone assignée à cet effet, un message lui indiquant que le montant doit être indiqué sans les centimes. Lorsqu'il aura terminé la saisie de ce champ, on appellera automatiquement la fonction verificationNum avec comme paramètre la valeur saisie. Cette fonction pourra par exemple tester que les caractères saisis sont uniquement des chiffres. Notons que la formulation "this.value" référence la valeur saisie dans le champ.

Voici les événements que l'on peut associer à la balise INPUT :

onBlur apparaît lorsque l'on perd le focus, c'est-à-dire le curseur de saisie quitte la zone de saisie des caractères.

onChange apparaît lorsque la valeur qui existait dans la zone changée, soit que l'on modifie la valeur par défaut, soit que l'on saisisse dans une case préalablement vide, soit que l'on modifie une valeur précédemment acquise.

onFocus apparaît dès que l'on clique dans la case de saisie.

onSelect apparaît lorsque l'on sélectionne le texte dans la zone de saisie.

Les événements se programment toujours de la façon suivante :

Nom_d_evenement=fonction_de_traitement(parametre_1, parametre_2, parametre_n ...)

Même si aucun paramètre n'est nécessaire pour traiter l'événement, le jeu de parenthèses est obligatoire que l'on verra par la suite.

Exemple de traitement d'événements dans la balise <INPUT> :

L'exemple suivant illustre le fonctionnement des événements onFocus et onChange. Pour l'instant, on peut ne pas s'attacher au codage des deux fonctions, mais il est important de faire le lien entre ces fonctions et leurs spécifications dans la balise HTML.

<HTML>

<HEAD>

<TITLE> Test Balise Input </TITLE>

<SCRIPT>

function aideContexte(texte) {

// Affichage dans la ligne de la barre URL du Browser

// et du message qui est re&ccedil;u dans l'argument "texte"

status="texte";

}

function verifNum(valeur) {

// V&eacute;rification que la cha&icirc;ne de caract&egrave;re repr&eacute;sent&eacute;e par l'argument

// "valeur" ne contient que des caract&egrave;res num&eacute;riques

for (var i=0; i<valeur.length; i++) {

var caractere=valeur.substring(i, i+1);

if (!(caractere > "0" && caractere < "9" )) {

alert ("Entrez des chiffres ou des nombres entier uniquement ! ");

return false;

}

}

return true;

}

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#CCCCCC">

<CENTER>

<H2> <BR> <BR> <font color="#800000"> ENTREZ UNIQUEMENT QUE DES CHIFFRES compris entre 1 &agrave; 8, Exemple : "12345678" </font> </H2>

<H2> <a href="Sommaire_HTML_Programmes.php">Retour au sommaire PHP</a> </H2>

<FORM NAME="FormFchier"> <BR> <BR> <BR> <BR>

<INPUT NAME="montant" STYLE="font-weight:bold; color:#FFFF00; height:20px; font-size:16px; background-color:#800000" value="" onFocus="aideContexte('indiquez le montant sans les centimes')" onChange="verifNum(this.value)"> <BR> <BR> <BR> <BR>

<INPUT TYPE="submit" name="montant" value="Valider" onClick="verifNum()">

</FORM>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Nous devons apporter quelques mots d'explication sur la fonction verifNum. On effectue un balayaye de tous les caractères contenus dans la chaîne "valeur" à l'aide d'une boucle for commençant au premier caractère (i=0) et se terminant au dernier (i<valeur.length;). L'extraction d'un caractère de la chaîne est obtenue par la méthode substring. On teste ensuite pour chacun des caractères s'il appartient à l'ensemble des chiffres de (0 à 9).

On verra au cours de nos leçons JavaScript Les instructions de base pour le codage des instructions ainsi que les chaînes de caractères comme objets pour la méthode substring.

<INPUT TYPE="PASSWORD"> :

Cette balise est identique à l'objet TEXT que nous venons de décrire pour ce qui concerne ses propriétés et ses méthodes, mais il n'a AUCUN événement associé. Il est utilisé pour saisir une information confidentielle (mot de passe par exemple). Dans cette zone, les caractères tapés sont toujours remplacés par une étoile.

<font face="Arial" size="3" color="#000000">Entrez votre mot de passe : </font> <INPUT SIZE="10" NAME="Mot_de_Passe" align="absmiddle" TYPE="PASSWORD" STYLE="font-weight:bold; color:#000000; height:20px; font-size:14px; background-color:#CCCCCC" value="">

Exemple ; Entrez votre mot de passe : Entrez votre mot de passe :

<INPUT TYPE="SUBMIT"> :

Si le formulaire ne comportait qu'une balise <INPUT>, on pourrait déclencher le traitement simplement, en tapant le caractère "return" et en appyant sur entrée de votre clavier. Si le formulaire comporte plusieurs éléments de saisie, il devient alors nécessaire de disposer d'un ou plusieurs éléments de déclenchement.

La balise <INPUT> dont l'attribut TYPE prend la valeur SUBMIT définit un bouton qui déclenche l'envoie de tous les champs du formulaire vers le script CGI de traitement.

Il peut y avoir plusieurs boutons SUBMIT dans un formulaire, en fonction de l'opération que l'on désire effectuer. Par exemple, après s'être identifié auprès de sa banque, on trouvera des boutons SUBMIT pour consulter son compte, commander un chéquier, effectuer un virement, etc.).

L'attribut NAME :

Cet attribut est souvent omis lorsqu'il existe un seul bouton de soumission pour le formulaire. Il peut cependant servir lorsque l'on réalise un formulaire, en plusieurs étapes (plusieurs pages HTML différentes) et que le script CGI qui génère les pages est toujours le même. Une des méthodes possibles pour reconnaître quelle est la page qui envoie des données est d'analyser le nom associer au bouton qui a provoqué l'appel.

L'attribut VALUE :

Il permet de spécifier essentiellement le texte qui sera inscrit sur le bouton, mais aussi d'identifier le bouton qui a été sollicité dans le cas où il existerait plusieurs boutons de soumission portant le même nom sur la même page.

<INPUT NAME="envoyer" TYPE="submit" VALUE="Valider">

Ce qui provoquera l'affichage suivant :

Les propriétés de l'objet SUBMIT :

Il possède trois propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur affichée sur le bouton.

type retourne le type de l'objet (submit).

document.FormFichier[n] qui va renvoyer l'envoi.

document.FormFichier.envoi.name qui va renvoyer l'envoi.

document.FormFichier[n].value qui va renvoyer Validez.

document.FormFichier.envoi.value qui va renvoyer Validez.

document.FormFichier[n].type qui va renvoyer submit.

document.FormFichier.envoi.type qui va renvoyer submit.

Les méthodes de l'objet SUBMIT :

La seule méthode applicable sur l'objet SUBMIT est la méthode click.

Cette méthode permet de simuler dans le script JavaScript l'action qui fait l'utilisation, en cliquant sur le bouton.

Toujours dans notre exemple, si dans une fonction JavaScript, on programme l'instruction suivante :

document.FormFichier.envoi.click()

Cela aura le même effet que d'appuyer sur le bouton.

Dans quel cas cela peut-il être utile ? Imaginons un formulaire avec un certain nombre de champs de saisie. A chaque saisie d'un champ, un programme JavaScript s'exécute, teste la validité de la donnée acquise et la stocke en mémoire. Lorsque la dernière donnée est saisie, le programme effectue automatiquement la soumission en "cliquant lui-même" sur le bouton. Le bouton SUBMIT ne sera utilisé que si on l'on souhaite envoyer le formulaire partiellement rempli.

L'événement associé à l'objet SUBMIT :

L'événement associé au bouton de soumission est onClick qui permet d'exécuter une fonction lorsque l'utilisateur appuie sur le bouton de soumission.

Exemple : <INPUT NAME="envoyer" TYPE="submit" value="Valider" onClick="verifNum()">

<INPUT TYPE="CHECKBOX"> :

Le type CHECKBOX sert à définir des ensembles de cases à cocher permettant un choix multiple entre différentes valeurs attribuables à une même variable (définie par NAME) ou à des variables différentes. Ce type d'élément, dans une utilisation traditionnelle pourrait tout à fait être comparé à une liste à sélection multiple. Nous verrons dans l'exemple JavaScript que l'on peut réaliser avec cet élément des fonctionnements plus astucieux.

Les balises HTML suivantes :

<INPUT TYPE="checkbox" NAME="selection" VALUE="Mecanique auto"> Mécanique <BR>

<INPUT TYPE="checkbox" NAME="selection" VALUE="Romancier"> Écriture <BR>

<INPUT TYPE="checkbox" NAME="selection" VALUE="Physique"> Énergie <BR>

<INPUT TYPE="checkbox" NAME="selection" VALUE="Electronique" checked> Synchronisation horizontale <BR>

<INPUT TYPE="checkbox" NAME="selection" VALUE="Informatique"> JavaScript

Ce qui provoqueront l'affichage ci-après :

Mécanique
Écriture
Énergie
Synchronisation horizontale
JavaScript

L'attribut NAME :

Il permet de nommer les éléments de case à cocher, avec un même nom pour plusieurs éléments ou avec des noms différents pour chaque élément.

L'attribut VALUE :

Cet attribut permet de spécifier la valeur envoyée vers le script, cette valeur étant identifiée par l'attribut NAME.

L'attribut CHECKED :

Il permet de positionner par défaut le bouton en mode validé (bouton enfoncé ou bouton coché ou encore case à cocher, selon le type de plate-forme).

Les propriétés de l'objet CHECKBOX :

Cet objet possède cinq propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur (value) programmée dans la balise.

type retourne le type de l'objet (checkbox).

checked retourne true si la case est validée, false dans le cas contraire.

defaultChecked retourne true si la case est validée par la balise (attribut CHECKED), false dans le cas contraire.

Dans notre exemple, un nom unique (selection) a été choisi pour les cinq balises ci-dessus. Cet ensemble se comporte donc comme un tableau, si bien qu'on accède aux propriétés par leurs indices. Attention, un formulaire peut être considéré comme un tableau : On a dans ce cas un tableau de tableau nécessitant deux indices [k, n] k représente l'indice de l'ensemble des balises selection, et n l'indice d'un des éléments de selection que nous avions pris comme exemple.

document.FormFichier[n].name qui renvoie la selection mais aussi :

document.FormFichier[k,n].name qui renvoie la selection

document.FormFichier.selection[n].name qui renvoie la selection

document.FormFichier.selection[n].value qui renvoie Mecanique auto pour n=0

document.FormFichier.selection[n].value qui renvoie Romancier pour n=1

document.FormFichier.selection[n].value qui renvoie Physique pour n=2

document.FormFichier.selection[n].value qui renvoie Electronique pour n=3

document.FormFichier.selection[n].value qui renvoie Informatique pour n=4

Mais aussi :

document.FormFichier.[k,n].value qui renvoie Mecanique auto pour n=0

document.FormFichier.[k,n].value qui renvoie Romancier pour n=1

document.FormFichier.[k,n].value qui renvoie Physique pour n=2

document.FormFichier.[k,n].value qui renvoie Electronique pour n=3

document.FormFichier.[k,n].value qui renvoie Informatique pour n=4

document.FormFichier.selection[n].type qui renvoie checkbox.

document.FormFichier.selection[n].checked qui renvoie true pour n=0

document.FormFichier.selection[n].defaultChecked qui renvoie true pour n=0

Ces derniers exemples peuvent bien sûr être référencés avec un double indice.

La méthode de l'objet CHECKBOX :

Il s'agit encore de la méthode Click, qui permet par une instruction du script de positionner la case en mode coché.

document.FormFichier.selection[n].Click()

L'événement associé à l'objet CHECKBOX :

L'événement associé à l'objet Checkbox est onClick qui permet d'exécuter une fonction lorsque l'utilisateur coche la case correspondante.

<INPUT NAME="selection" TYPE="checkbox" value="Valider" onClick="verifNum()">

Exemple de traitement d'événements sur la CHECKBOX :

Dans le TGV, il n'est possible de se faire servir un repas à sa place qu'en première classe.

Le formulaire ci-dessous fonctionne ainsi :

Si l'on coche la "Première classe", on décoche automatiquement la "Deuxième classe". On peut alors cocher la case "Demande de repas".

Si l'on coche la "Deuxième classe", on décoche automatiquement la Première classe" et on décoche aussi la case de "Demande de repas".

Si l'on coche la "Demande de repas", on décoche automatiquement la "Deuxième classe" si elle était cochée, et on coche automatiquement la "Première classe".

Voici le code HTML avec feuille de style :

<HTML>

       <HEAD>

               <TITLE> Demande Repas </TITLE>

                         <STYLE TYPE="text/css">

                               * { margin: 0; }

                               html { font: 14px / 20px Arial, sans-serif }

                               div { opacity: 1; position: absolute }

                               #div1 { opacity: 1; top: 240px; left: 220px; width: 140px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                               #div2 { opacity: 1; top: 0px; left: 171px; width: 150px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #FF0000; }

                               #div3 { opacity: 1; top: 0px; left: 181px; width: 145px; height: 18px; border: 1px dashed #696; padding: 15px; color: #FFFFFF; background-color: #000000; }

                               #div4 { opacity: 1; top: 30px; left: 150px; width: 900px; height: 18px; border: 1px dashed #900; padding: 20px 20px 20px; background-color: #FFDDFF }

                               body { background-color: #CCCCCC }

                         </STYLE>

                                   <SCRIPT LANGUAGE="JavaScript">

                                   function Demande_repas(NumDaniel) {

                                   // Classe[0] = 1&egrave;re classe

                                   // Classe[1] = 2&egrave;me classe

                                   if (NumDaniel==1) {

                                   // On a cliqu&eacute; sur 1&egrave;re classe qui &eacute;tait coch&eacute; ou d&eacute;coch&eacute;

                                   // On d&eacute;clique 2&egrave;me classe

                                   this.document.form1.classe[1].checked=false;

                                   if (this.document.form1.classe[0].checked=false) {

                                   // Si on d&eacute;coche, alors, on d&eacute;coche aussi repas

                                   this.document.form1.repas.checked=false;

                             }

                       }

                                   if (NumDaniel==2) {

                                   // On a cliqu&eacute; sur 2&egrave;me classe

                                   // On d&eacute;clique premi&egrave;re classe

                                   this.document.form1.classe[0].checked=false;

                                   // On d&eacute;clique repas

                                   this.document.form1.repas.checked=false;

                       }

                                   if (NumDaniel==3) {

                                   // On a cliqu&eacute; sur repas

                                   if (this.document.form1.classe[1].checked=true)

                                   // Si 2&egrave;me classe &eacute;tait coch&eacute;e, alors, on le d&eacute;coche

                                   this.document.form1.classe[1].checked=false;

                                   // Dans tous les cas, on coche alors 1&egrave;re classe

                                   this.document.form1.classe[0].checked=true;

                  }

             }

                                   </SCRIPT>

       </HEAD>

            <BODY> <BR> <BR> <BR> <CENTER>

            <DIV ID="div4"> <font face="Arial" size="5"> <b> Les repas doivent &ecirc;tre servis uniquement qu'en premi&egrave;re classe. Eh ben oui !!! </b> </font>

            <FORM NAME="form1"> <BR> <BR> <BR>

<DIV ID="div1"> <INPUT TYPE="checkbox" name="classe" value="1" onClick="Demande_repas(1)"> <b> Premi&egrave;re classe

<DIV ID="div2"> <INPUT TYPE="checkbox" name="classe" value="2" onClick="Demande_repas(2)"> Deuxi&egrave;me classe

<DIV ID="div3"> <INPUT TYPE="checkbox" name="repas" value="3" onClick="Demande_repas(3)"> Demande Repas </b>

            </FORM> </CENTER>

            </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Les commentaires (// "couleur verte foncée") insérés dans le code source expliquent le fonctionnement du script.

<INPUT TYPE="RADIO">

On utilise généralement un ensemble de boutons radio pour choisir une et une seule option parmi n. Le fonctionnement peut encore être dans ce cas assimilé à celui d'une liste à sélection unique. Cliquer sur un bouton "déclique" automatiquement les autres. L'exemple suivant donne un choix exclusif entre Disquette, CD-Rom, Disque dur, Carte mère, Bloc d'alimentation.

<INPUT TYPE="radio" NAME="materiels" VALUE="CD" checked> CD-Rom

<INPUT TYPE="radio" NAME="materiels" VALUE="Disque"> Disquette

<INPUT TYPE="radio" NAME="materiels" VALUE="DisqueDur"> Disque dur

<INPUT TYPE="radio" NAME="materiels" VALUE="Carte"> Carte mère

<INPUT TYPE="radio" NAME="materiels" VALUE="Alimentation"> Bloc d'alimentation

Provoquerons l'affichage ci-après : CD-Rom Disquette Disque dur Carte mère Bloc d'alimentation

L'attribut NAME :

Le browser identifie un ensemble de boutons radio par le fait qu'ils possèdent chacun le même nom (attribut NAME).

L'attribut CHECKED :

Il permet de sélectionner une option par défaut ou de valider l'option la plus probable. Dans l'exemple ci-dessus, le bouton (CD-ROM) est enfoncé (ou coché).

Les propriétés de l'objet RADIO :

Cet objet possède sept propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur (value) programmée dans la balise.

type retourne le type de l'objet (radio).

checked retourne true si la case est validée, false dans le cas contraire.

defaultChecked returne true si la case est validée par la balise (attribut CHECKED), false dans le cas contraire.

index dans le rang (l'indice) du bouton qui est enfoncé.

length retourne le nombre d'éléments de type radio ayant le même attribut NAME (donc définissant un bloc).

Dans notre exemple, un nom unique "materiels" a été choisi pour les cinq balises. Cet ensemble se comporte donc comme un tableau, si bien qu'on accède aux propriétés par leurs indices. On est toujours dans le cas d'un formulaire pouvant être considéré comme un tableau et on doit toujours considérer le double indice [k,n] k représente l'indice de l'ensemble des balises "materiels", et n l'indice d'un des éléments de "materiels".

document.FormFichier[n].name qui renvoie materiels. Mais aussi :

document.FormFichier[k,n].name qui renvoie materiels.

document.FormFichiermateriels[n].name qui renvoie materiels.

document.FormFichier.materiels[n].value qui renvoie CD pour n=0.

document.FormFichier.materiels[n].value qui renvoie Disque pour n=1.

document.FormFichier.materiels[n].value qui renvoie DisqueDur pour n=2.

document.FormFichier.materiels[n].value qui renvoie Carte pour n=3.

document.FormFichier.materiels[n].value qui renvoie Alimentation pour n=4.

Mais aussi :

document.FormFichier.[k,n].value qui renvoie CD pour n=0.

document.FormFichier.[k,n].value qui renvoie Disque pour n=1.

document.FormFichier.[k,n].value qui renvoie DisqueDur pour n=2.

document.FormFichier.[k,n].value qui renvoie Carte pour n=3.

document.FormFichier.[k,n].value qui renvoie Alimentation pour n=4.

document.FormFichier.materiels[n].type qui renvoie radio

document.FormFichier.materiels[n].checked qui renvoie true pour n=0.

document.FormFichier.materiels[n].defaultChecked qui renvoie true pour n=0.

Ces derniers exemples peuvent bien sûr être aussi référencés avec un double indice.

La méthode de l'objet RADIO :

Il s'agit là encore de la méthode Click, qui permet par une instruction du script, de positionner la case en mode coché.

document.FormFichier.materiels[n].click()

L'événement associé à l'objet RADIO :

L'événement associé à l'objet RADIO est onClick, qui permet d'exécuter une fonction lorsque l'utilisateur coche la case correspondante.

<INPUT TYPE="radio" NAME="materiels" VALUE="CD" onClick="demande('cd')" checked> CD-ROM

<INPUT TYPE="radio" NAME="materiels" VALUE="Disque" onClick="demande('disk')"> Disquette

<INPUT TYPE="RESET"> :

Ce bouton permet à tout moment d'effacer les données qui sont en cours de saisie sur le formulaire.

L'attribut NAME :

C'est l'attribut qui permet de nommer le bouton à l'intérieur du formulaire.

L'attribut VALUE :

Cet attribut sert essentiellement à afficher un texte sur le bouton.

<INPUT NAME="initialisation" TYPE="reset" VALUE="Effacer">

Donne l'affichage ci-après :

Les propriétés de l'objet RESET :

Cet objet possède trois propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur (value) programmée dans la balise.

type qui retourne reset.

La méthode de l'objet RESET :

Il s'agit encore de la méthode Click, qui permet par une instruction du script réinitialiser les données du formulaire. Encore une fois, précisons que la réinitialisation a lieu lors de l'exécution d'une instruction et non sur le clic que peut faire l'utilisateur. Le clic de l'utilisateur génère un événement.

document.FormFichier.initialisation.click()

L'événement associé à l'objet RESET :

L'événement associé à cet objet est onClick, qui permet d'exécuter une fonction lorsque l'utilisateur clique sur le bouton.

<INPUT TYPE="reset" NAME="init" value="Effacer" onClick="demandeEfface()">

Fin de ce deuxième chapitre, le prochain sera consacré "aux balises définissant les composants du formulaire qui sera la suite de cette leçon", toujours dans le même domaine HTML.


Les Balises Select, Option, Textarea, Type Hidden

Les Balises Select, Option, Textarea, Type Hidden :

<SELECT> et <OPTION> :

Ce sont les balises réservées à la création de listes ou de menus dans lesquels l'utilisateur pourra sélectionner des éléments. Ces balises permettent de fabriquer deux objets graphiquement différents ; les menus déroulants (plus communément appelés pop-lists et des listes à ascenseur (scrolled-lists). Tous les items d'une liste seront spécifiés entre la balise de début <SELECT> et la balise de fin </SELECT> à l'aide d'une balise <OPTION>.

La pop-list se présente sous la forme d'un bouton sur lequel est inscrit un seul des items de la liste. Lorsque l'on clique sur le bouton, on déploie le contenu complet de la liste. Ce type d'élément permet de prendre peu de place au niveau de la page, la liste n'apparaissant qu'à la demande de l'utilisateur.

Les scrolled-lists sont des listes apparaissant dans une fenêtre et dont on peut régler le nombre de lignes visibles. Si la liste contient plus d'éléments que le nombre de lignes programmées, un ascenseur apparaît automatiquement.

L'attribut NAME de la balise <SELECT> :

Encore une fois, cet attribut permet de nommer l'objet à l'intérieur du formulaire. L'objet SELECT est cependant un peu plus complexe, car c'est en fait l'ensemble des balises <SELECT> et <OPTION> qui représentent l'objet select.

L'attribut SIZE de la balise <SELECT> :

Si la valeur qui affecte l'attribut SIZE est supérieure à 1, l'objet select est une scrolled-list ; dans le cas contraire ou s'il est absent, l'objet est une pop-list.

L'attribut MULTIPLE de la balise <SELECT> :

Cet attribut n'a de sens que dans une scrolled-list. Il autorise la sélection simultanée de plusieurs items de la liste.

L'attribut VALUE de la balise <OPTION> :

Cet attribut permet de définir la valeur qui va être passée au script CGI lorsque l'option est sélectionnée.

L'attribut SELECTED de la balise <OPTION> :

Dans le cas d'une pop-list, cet attribut définit l'option qui est sélectionnée par défaut sur le bouton.

Dans le cas d'une scrolled-list, il permet de présélectionner un item de la liste.

Le code HTML suivant permet de réaliser une pop-list :

<SELECT NAME="MonSite">

<OPTION VALUE="Electronique-et-informatique.fr"> Electronique (Jean-Pierre)

<OPTION VALUE="Informatique.fr"> Informatique (Jennifer)

<OPTION VALUE="Mecanique_generale.com" SELECTED> Automobile (Vanessa)

</SELECT>

Ce qui provoquera l'affichage ci-après :

Tandis que le code suivant permet de générer une scrolled-list :

<SELECT NAME="Menu_html" SIZE="6">

<OPTION VALUE="intro"> Introduction

<OPTION VALUE="hypertech"> Technique de l'hypertexte

<OPTION VALUE="environ"> L'environnement

<OPTION VALUE="url"> L'adressage des documents

<OPTION VALUE="Struct"> La structure du langage

<OPTION VALUE="balise"> Les balises

<OPTION VALUE="accent"> L'accentuation

<OPTION VALUE="table"> Les tableaux

<OPTION VALUE="images"> Les images

<OPTION VALUE="carac"> Caract&egrave;res en graisse choisie

</SELECT>

Ce qui provoquera l'affichage ci-après :

Si l'on modifie la première ligne avec l'introduction de l'attribut multiple :

<SELECT NAME="Menu_html" SIZE="6" MULTIPLE>

<OPTION VALUE="intro"> Introduction

<OPTION VALUE="hypertech"> Technique de l'hypertexte

<OPTION VALUE="environ"> L'environnement

<OPTION VALUE="url"> L'adressage des documents

<OPTION VALUE="Struct"> La structure du langage

<OPTION VALUE="balise"> Les balises

<OPTION VALUE="accent"> L'accentuation

<OPTION VALUE="table"> Les tableaux

<OPTION VALUE="images"> Les images

<OPTION VALUE="carac"> Caract&egrave;res en graisse choisie

</SELECT>

Cela permet alors ce type de sélection, en appuyant bien sût sur la touche shwit du clavier pour sélectionner plusieurs items.

Les propriétés de l'objet SELECT :

Cet objet possède les propriétés suivantes :

name donne le nom qui a été choisi pour cette balise.

type done le type de l'objet SELECT, soit :

select-one pour une pop-list.

select-multiple pour une liste à sélection multiple.

select pour une liste à sélection simple.

selectedIndex reflète l'index de l'option sélectionnée pour une liste à sélection unique ou une pop-list, et l'index de la première option sélectionnée pour une liste à sélection multiple. La propriété selectedIndex est la plus efficace pour connaître l'index de l'option sélectionnée d'une liste à sélection simple. Si aucune option n'est sélectionnée, la valeur de l'index retournée est égale à -1.

Si l'on veut connaître les options sélectionnées dans une liste à sélection multiple, il convient de scruter tous les éléments (options) de la liste et de lire la propriété selected de chacun, comme le montre l'exemple suivant :

<HTML>

<HEAD>

<TITLE> Lire la S&eacute;lection Multiple </TITLE>

<SCRIPT>

function LireLesSelections() {

var Parametre = location.search.substring(1).split("&");

var temp = Parametre[0].split("=");

varSelection = unescape(temp[0]);

if(varSelection == "") return;

value = unescape(temp[1]);

alert(varSelection + "=" + value);

}

window.onload=LireLesSelections;

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#CCCCCC">

<CENTER> <BR> <BR>

<font face="Arial" size="5" color="#800000"> <b> Observez bien la barre de l'URL, en s&eacute;lectionnant plusieurs noms par exemple ! </b> </font>

<FORM NAME="F1"> <BR> <BR>

<select NAME="Propriete" size="7" multiple>

<option value="Operateur_1"> Jean

<option value="Operateur_2"> Pierre

<option value="Operateur_3"> Marie-Pierre

<option value="Operateur_4"> Jennifer

<option value="Operateur_5"> Dupond

<option value="Operateur_6"> Val&eacute;rie

<option value="Operateur_7"> Patty

<option value="Operateur_8"> Marie-France

</select> <BR> <BR> <BR>

<input type="submit" name="Select" value="Valider" onClick="LireLesSelections()">

</FORM>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Les méthodes de l'objet SELECT :

blur et focus sont des méthodes qui n'ont pas vraiment d'utilité. Si la méthode focus() permet bien de donner le focus sur une liste (et non sur une pop-list où cette méthode est sans effet), elle ne permet pas d'en sélectionner une option. En fait, elle n'a d'autre effet que d'attirer l'attention sur la liste. La méthode blur() doit permettre de forcer la désélection de la liste.

Les événements associés à l'objet SELECT :

Les événements associés à l'objet sont :

onChange, apparaît lorsque l'utilisateur effectue un changement d'une option (sélection ou désélection).

onFocus, apparaît si l'on clique sur une option quelconque d'une liste. Il n'y a pas d'événement onFocus sur une pop-list.

onBlur, apparaît lorsque, après avoir cliqué sur une option d'une liste, on clique en dehors de cette liste. Il n'y a pas d'événement onBlur sur une pop-list.

Les propriétés des options de l'objet SELECT :

L'objet SELECT est certainement l'objet le plus intéressant parmi les éléments constituant une interface de saisie. En effet, les options composant cet objet peuvent être construites ou modifiées dynamiquement par du code JavaScript. Avant de passer à des exemples concrets, examinons les différentes propriétés de l'option :

defaultSelected, renvoie true ou false selon que l'option est celle qui est sélectionnée par défaut. Si aucune option d'une pop-list ne possède d'attribut selected, c'est le premier élément de la liste qui est considéré comme option sélectionnée par défaut.

Dans une liste standard (size > 1) defaultSelected n'est vrai que si une option est explicitement marquée avec l'attribut selected.

selected, renvoie true si l'option est sélectionnée, false sinon.

text, renvoie le texte associé à l'option (<option value="fruits"> poire renvoie poire).

value, renvoie la valeur associée à l'option (<option value="fruits"> poire renvoie fruits).

Exemple de création et de suppression d'options :

Dans cet exemple, on se propose d'afficher dans la liste de gauche un choix de fruits. Le lecteur peut transférer les fruits de son choix dans la liste de droite, en cliquant sur le bouton >>. Il peut revenir sur son choix, en renvoyant le fruit dans sa liste d'origine par un clic sur le bouton <<.

<HTML>

<HEAD>

<TITLE> Transfert de son choix </TITLE>

<SCRIPT>

function A_Transfert_Destinaion_Vers_B() {

indexA=document.Transfert.Source.options.selectedIndex;

if (indexA < 0) return;

valeur=document.Transfert.Source.options[indexA].text;

document.Transfert.Source.options[indexA]=null;

a = new Option(valeur);

indexB=document.Transfert.Destination.options.length;

document.Transfert.Destination.options[indexB]=a;

}

function B_Transfert_Source_Vers_A() {

indexB=document.Transfert.Destination.options.selectedIndex;

if (indexB < 0) return;

valeur=document.Transfert.Destination.options[indexB].text;

document.Transfert.Destination.options[indexB]=null;

a = new Option(valeur);

indexA=document.Transfert.Source.options.length;

document.Transfert.Source.options[indexA]=a;

}

</SCRIPT>

<STYLE TYPE="TEXT/CSS">

#Ma_Selection

{

width : 140px; background: #DEDEDE; color: #000000;

}

</STYLE>

</HEAD>

<BODY BGCOLOR="#CCCCCC">

<CENTER> <BR> <BR> <BR>

<H1> Vous pouvez s&eacute;lectionner plusieurs items dans la liste de gauche </H1> <BR> <BR> <BR>

<TABLE bordercolor="#606060" bgcolor="#606060"> <TR> <TD>

<FORM NAME="Transfert">

<SELECT ID="Ma_Selection" MULTIPLE SIZE="7" NAME="Source">

<OPTGROUP LABEL="SOURCE">

<OPTION>Citrons

<OPTION>Oranges

<OPTION>Pamplemousses

<OPTION>Cl&eacute;mentines

<OPTION>Kiwis

<OPTION>Bergamotes

<OPTION>Grenades

<OPTION>Pommes

<OPTION>Bananes

<OPTION>Yaourt Citron

<OPTION>Cerises

</SELECT>

<TD>

<INPUT TYPE="button" value=">>>" onClick="A_Transfert_Destinaion_Vers_B()"> <BR> <BR>

<INPUT TYPE="button" value="<<<" onClick="B_Transfert_Source_Vers_A()">

<TD>

<SELECT ID="Ma_Selection" MULTIPLE SIZE="7" NAME="Destination">

<OPTGROUP LABEL="DESTINATION">

</SELECT>

</TR> </TD> </TD> </TD>

</FORM>

</TABLE>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

Comment ce Script fonctionne-t-il ? Le clic sur le bouton >>> entraîne l'exécution de la fonction A_Transfert_Destinaion_Vers_B(). Dans cette fonction, on commence par repérer le rang de l'élément qui a été sélectionné et on le range dans la variable "indexA" (indexA=document.Transfert.Source.options.selectedIndex). Si cette variable contient une valeur inférieure à zéro, c'est qu'aucun élément n'est sélectionné, dans ce cas, on sort de la fonction (if (indexA < 0) return;).

Si un élément (un fruit) a été sélectionné, on récupère dans la variable valeur la chaîne de caractères contenant le nom du fruit (valeur=document.Transfert.Source.options[indexA].text). On efface le fruit choisi de la liste de gauche, en supprimant l'option correspondante de la liste (document.Transfert.Source.options[indexA]=null). Pour ce faire, on affecte la valeur null à l'option considérée. On utilise ensuite le constructeur d'option pour construire une option dont le texte représente le fruit pris dans la liste de gauche et dont on avait conservé le nom dans la variable valeur (a = new Option(valeur)) ; cette option est conservée dans la variable a. On détermine la longueur de la liste de droite et on la stocke dans la variable indexB (indexB=document.Transfert.Destination.options.length). Comme la numérotation des options commence à zéro, indexB correspond à l'indice de l'option que nous sommes en train de transférer de la gauche vers la droite. Le transfert est enfin réalisé (document.Transfert.Destination.options[indexB]=a).

La fonction inverse B_Transfert_Source_Vers_A() fonctionne de façon tout à fait symétrique.

Exemple de modification du texte des options :

Dans ce deuxième exemple, nous allons vous montrer comment on peut changer dynamiquement le texte d'une option dans un menu déroulant (pop-list). Le menu déroulant du bas permet de choisir la langue (Français ou Anglais) ; selon la langue choisie, le menu déroulant du haut affichera automatiquement les jours de la semaine dans la langue sélectionnée.

<HTML>

<HEAD>

<TITLE> Bilingue Fran&ccedil;ais Anglais </TITLE>

<SCRIPT>

function Bilingue_Francais_Anglais (forme) {

if (forme.langue.options[1].selected == true) {

forme.jours.options[0].text = "MONDAY"

forme.jours.options[1].text = "TUESDAY"

forme.jours.options[2].text = "WENESDAY"

forme.jours.options[3].text = "THURSDAY"

forme.jours.options[4].text = "FRIDAY"

forme.jours.options[5].text = "SATURDAY"

forme.jours.options[6].text = "SUNDAY"

}

else {

forme.jours.options[0].text = "LUNDI"

forme.jours.options[1].text = "MARDI"

forme.jours.options[2].text = "MERCREDI"

forme.jours.options[3].text = "JEUDI"

forme.jours.options[4].text = "VENDREDI"

forme.jours.options[5].text = "SAMEDI"

forme.jours.options[6].text = "DIMANCHE"

}

}

</SCRIPT>

<STYLE TYPE="TEXT/CSS">

#Semaine

{

width:120px; background: #DADADA; color: #000000;

}

</STYLE>

</HEAD>

<BODY BGCOLOR="#CCCCCC"> <CENTER> <BR> <BR>

<FORM>

<select id="Semaine" name="jours">

<option>LUNDI

<option>MARDI

<option>MERCREDI

<option>JEUDI

<option>VENDREDI

<option>SAMEDI

<option>DIMANCHE

</select>

<p>

<select id ="Semaine" name="langue" onChange="Bilingue_Francais_Anglais(this.form)">

<option selected>FRANCAIS

<option>ENGLAIS

</select>

</FORM>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6].

Cette petite interface fonctionne de la façon suivante : au chargement de la page, on positionne l'interface en français ; le menu "langue" affiche français et le menu déroulant des jours de la semaine est en français.

Dans le second menu déroulant permettant de choisir la langue, on traite l'événement onChange qui, lorsqu'il survient, appelle la fonction Bilingue_Francais_Anglais. Cette fonction teste si la seconde option de la liste (celle dont l'indice est à 1 et représente anglais) est sélectionnée (if (forme.langue.options[1].selected == true)). Si tel est le cas, on bascule l'interface en "anglais" en modifiant le texte des jours de la semaine (forme.jours.options[0].text = "MONDAY" ...).

Si les balises <OPTION> avaient défini des valeurs (option value="...">, il aurait été possible de les changer aussi en modifiant la propriété "value" (forme.jours.options[0].value="...").

Exemple pour récapituler le fonctionnement des options de l'objet SELECT :

Dans ce dernier exemple, on trouvera toutes les techniques de manipulation des listes. Il montre comment créer une option, comment rechercher les options sélectionnées dans une liste à sélection multiple, comment désélectionner des options, et enfin, comment supprimer des options.

<HTML>

<HEAD>

<TITLE> R&eacute;capitulatif des Options </TITLE>

<SCRIPT LANGUAGE="JavaScript">

function Creation_Options() {

// Cr&eacute;ation d'une option dans la liste

if (document.forms[0].elements[0].value="") return;

n = new Option(document.forms[0].elements[1].value);

var index = document.forms[0].elements[0].options.length;

document.forms[0].elements[0].options[index] = n;

document.forms[0].elements[1].value="";

}

function Recherche_Selection() {

// Recherche de l'option s&eacute;lectionn&eacute;e

for (i=0; i < document.forms[0].elements[0].options.length; i++) {

if (document.forms[0].elements[0].options[i].selected)

alert ("Votre Recherche de S&eacute;lection est le N&deg; " + i);

}

}

function Deselection_Options() {

// D&eacute;s&eacute;lection de toutes les options s&eacute;lectionn&eacute;es

for (i=0; i<document.forms[0].elements[0].options.length; i++) {

if (document.forms[0].elements[0].options[i].selected)

document.forms[0].elements[0].options[i].selected = false;

}

}

function Effacement_Options() {

// Effacement de toutes les options s&eacute;lectionn&eacute;es

index = document.forms[0].elements[0].options.length;

for (var i = index-1; i >=0; i--) {

if (document.forms[0].elements[0].options[i].selected) {

document.forms[0].elements[0].options[i] = null;

}

}

}

</SCRIPT>

<STYLE TYPE="TEXT/CSS">

#Ma_Selection { width: 240px; background: #DEDEDE; color: #003500; }

#Ma_Liste { width: 140px; background: #DEDEDE; color: #000000; }

</STYLE>

</HEAD>

<BODY BGCOLOR="CCCCCC">

<FORM NAME="Formulaire"> <BR> <BR> <BR> <BR> <CENTER>

<SELECT ID="Ma_Selection" NAME="Source" SIZE="6" MULTIPLE>

</SELECT> <BR> <BR>

<font face="Arial" size="3" color="#800000"> <b> Entrez votre texte : </b> <BR> <INPUT ID="Ma_Liste" TYPE="Text" NAME="Text"> </font> <p>

<INPUT VALUE="Cr&eacute;er une Option" TYPE="BUTTON" onClick="Creation_Options()"> <BR> <BR>

<INPUT VALUE="Rechercher la S&eacute;lection" TYPE="BUTTON" onClick="Recherche_Selection()"> <BR> <BR>

<INPUT VALUE="Tout D&eacute;s&eacute;lectionner" TYPE="BUTTON" onClick="Deselection_Options()"> <BR> <BR>

<INPUT VALUE="Effacer les Options S&eacute;lectionn&eacute;es" TYPE="BUTTON" onClick="Effacement_Options()">

</FORM> </CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6 bis].

<TEXTAREA> :

Cette balise permet de créer une zone de texte, en spécifiant sa taille grâce aux valeurs que l'on associera aux attributs ROWS et COLS. ROWS indique le nombre de lignes de la fenêtre, tandis que COLS déinit le nombre de colonnes.

Dans cette fenêtre, il est possible de prédéfinir un texte (entre les balises <TEXTAREA> et </TEXTAREA>) que l'utilisateur pourra remplacer ou compléter par son propre texte.

<TEXTAREA NAME="commentaires" ROWS="10" COLS="30"> Entrez ici vos commentaires </TEXTAREA>

Ce qui provoquera l'affichage ci-après :

Attention ! Le bouton RESET du formulaire n'efface pas le texte prédéfini. Celui-ci doit être effacé manuellement.

Du point de vue JavaScript, l'objet TEXTAREA ce comporte exactement comme l'objet TEXT que nous avions vu dans la leçon précédente.

<INPUT TYPE="BUTTON"> :

Ce bouton n'a de sens que dans un contexte JavaScript. En effet, au niveau d'un CGI, il ne permet pas de collecter une valeur (il n'a pas d'état). D'autre part, il n'a pas un comportement préprogrammé comme le bouton submit qui permet d'envoyer les données, ou le bouton reset qui efface les données saisies. Son utilisation concernera donc essentiellement la génération d'événements déclenchant des fonctions JavaScript.

L'attribut NAME :

C'est attribut qui permet de nommer le bouton à l'intérieur du formulaire.

L'attribut VALUE :

Cet attribut sert essentiellement à afficher un texte sur le bouton.

<INPUT TYPE="button" NAME="test" VALUE="Lancer">

Ce qui provoquera l'affichage ci-après :

Les propriétés de l'objet BUTTON :

L'objet BUTTON possède deux propriétés :

name donne le nom qui a été choisi pour cette balise.

value retourne la valeur (value) programmée dans la balise.

La méthode de l'objet BUTTON :

Il s'agit encore de la méthode Click, qui permet par une instruction de script de réinitialiser les données du formulaire. Encore une fois, précisons que la réinitialisation a lieu lors de l'exécution d'une instruction et non sur le clic que peut faire l'utilisateur. Le clic de l'utilisateur génère un événement.

document.FormFichier.init.click()

L'événement associé à l'objet BUTTON :

L'événement associé à l'objet BUTTON est onClick, qui permet d'exécuter une fonction lorsque l'utilisateur clique sur le bouton.

<INPUT TYPE="reset" NAME="initialisation" VALUE="Effacer" onClick="efface()">

Exemple d'utilisation :

Cliquer sur le bouton "fermer" provoque la création au premier plan d'une fenêtre de confirmation de fermeture. Si l'on répond "OK", on ferme simultanément la fenêtre "Question" et la fenêtre principale qui contient le bouton "fermer".

NB : Cette fenêtre de confirmation n'apparaît pas si la fenêtre principale a été ouverte par une instruction JavaScript du type window.open...

<FORM> <INPUT TYPE="button" VALUE="Fermer" onClick="window.close()"> </FORM>

Important : sur certains browsers ne fonctionnent pas !

EXEMPLES :

Voici maintenant quelques exemples complets de formulaires :

Exemple 1 :

<HTML>

       <HEAD>

               <TITLE> Formulaire E-Mail </TITLE>

       </HEAD>

                   <BODY BGCOLOR="#CCCCCC"> <CENTER>

                         <H3> <BR> <BR> Regardez bien l'URL de votre navigateur ... <BR> <BR>

                         <FORM METHOD="get" ACTION="http://www.electronique-et-informatique.fr/"> Entrez votre E-Mail : &nbsp;

                         <INPUT TYPE="text" NAME="E-Mail"> &nbsp; puis &nbsp;

                         <INPUT TYPE="submit" NAME="Envoyer" VALUE="Valider">

                         </FORM> </H3> </CENTER>

                   </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

Exemple 2 :

<HTML>

       <HEAD>

               <TITLE> Formulaire E-Mail et Options </TITLE>

       </HEAD>

                   <BODY BGCOLOR="#CCCCCC"> <b> <BR> <BR> <BR> <CENTER>

                         <FORM METHOD="GET" ACTION="http://www.electronique-et-informatique.fr/">

                         &nbsp;&nbsp; <font face="Arial" size="3" color="#000000"> Entrez votre nom : </font>

                         <INPUT TYPE="text" NAME="NOM"> <BR> <p>

                         <font face="Arial" size="3" color="#000000"> Entrez votre E-Mail : </font>

                         <INPUT TYPE="text" NAME="E-Mail"> <BR> <BR> <BR> <BR>

                         <font face="Arial" size="3" color="#000000"> <i> Quel(s) micro-ordinateur(s) utilisez-vous ? </i> </font> <BR> <BR>

                         <font face="Arial" size="3" color="#000000"> &nbsp;&nbsp;&nbsp; <INPUT TYPE="checkbox" NAME="MICRO" VALUE="MAC"> Macintosh </font>

                         <font face="Arial" size="3" color="#000000"> &nbsp;&nbsp;&nbsp; <INPUT TYPE="checkbox" NAME="MICRO" VALUE="PC"> PC </font>

                         <font face="Arial" size="3" color="#000000"> &nbsp;&nbsp;&nbsp; <INPUT TYPE="checkbox" NAME="MICRO" VALUE="UNIX"> Station Unix </font> <p>

                         <BR> <BR> <BR>

                         <font face="Arial" size="3" color="#000000"> <i> M&eacute;dia de distribution &nbsp; </i>

                         <INPUT TYPE="radio" NAME="media" VALUE="CD"> CD-ROM

                         &nbsp;&nbsp; <INPUT TYPE="radio" NAME="media" VALUE="DISK"> Disquette </font> <BR> <BR>

                         <INPUT TYPE="submit" VALUE="Valider">

                         </FORM> </CENTER> </b>

                   </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

Exemple 3 ; pour démonstration avec la "Méthode POST" :

<HTML>

       <HEAD>

               <TITLE> Simple Formulaire </TITLE>

       </HEAD>

                   <BODY BGCOLOR="#CCCCCC"> <b> <BR> <BR> <BR> <CENTER>

                         <H2> A &eacute;viter de faire en langage HTML mais plut&ocirc;t en PHP que l'on verra plus tard ! </H2>

                         <H3> Comme vous pourriez vous rendre compte, lorsque l'on tape son mot de passe, tout le monde pourra voir ce dernier !!! Surtout en mode "GET" </H3>

                         <H2> Nous e&ucirc;mes d&eacute;sactiv&eacute; l'attribut "M&eacute;thode GET" </H2>

                         <font face="Arial" size="4" color="#005500"> NB : C'est uniquement un exemple pour vous familiariser avec le langage HTML </font> <BR> <BR> <BR>

                         <FORM METHOD="POST" ACTION="http://www.electronique-et-informatique.fr/">

                         &nbsp;&nbsp;&nbsp;&nbsp; <font face="Arial" size="3" color="#800000"> Choisissez un syst&egrave;me : </font>

                         <SELECT NAME="Envoyer">

                         <OPTION> Electronique

                         <OPTION SELECTED> Physique

                         <OPTION> G&eacute;om&eacute;trie

                         <OPTION> Math&eacute;matique

                         <OPTION> Formules Math&eacute;matiques

                         </SELECT> <BR> <BR> <BR>

                         <font face="Arial" size="3" color="#800000"> Entrez votre nom : &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font>

                         <INPUT TYPE="text" NAME="Username"> <BR> <BR> <BR>

                         <font face="Arial" size="3" color="#800000"> Entrez votre password : </font>

                         &nbsp;&nbsp; <INPUT TYPE="password" NAME="PassWord"> <BR> <BR>

                         <INPUT TYPE="SUBMIT" NAME="Eviter_de_Faire" VALUE="Envoyer">

                         </FORM> </CENTER> </b>

                   </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

Nous allons évoquer le même exemple sans rien changer concernant le code HTML de l'exemple 3, (ci-dessus du code HTML), mais cette fois-ci, en modifiant la "méthode POST" par la "méthode GET", vous observerez bien la différence entre ces deux méthodes dans la barre de l'URL de votre navigateur.

Exemple 3. bis ; pour démonstration avec la "Méthode GET" :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9. 1.].

Exemple 4 :

<HTML>

       <HEAD>

               <TITLE> Formulaire &agrave; S&eacute;lection Multiple </TITLE>

       </HEAD>

                   <BODY BGCOLOR="#CCCCCC"> <B> <BR> <BR> <BR> <CENTER>

                   <H1> Activation de l'attribut de la "m&eacute;thode GET" comme exemple </H1> <BR> <BR>

                   <H2> Choisissez les chapitres à imprimer </H2>

                         <FORM NAME="Multiple" METHOD="GET" ACTION="http://www.electronique-et-informatique.fr/">

                         <SELECT NAME="Test" SIZE="6" multiple>

                         <OPTION> Introduction

                         <OPTION> Technique hypertexte

                         <OPTION> Environnement HTML

                         <OPTION> Adressage des documents

                         <OPTION> La structure du langage

                         <OPTION> Les balises

                         <OPTION> Accentuation

                         <OPTION> Les tableaux

                         <OPTION> Les images

                         <OPTION> Les images cliquables

                         <OPTION> Les formulaires

                         <OPTION> La s&eacute;curit&eacute;

                         <OPTION> Informatique

                         </SELECT> <BR> <BR> <BR> <BR>

                         <INPUT TYPE="SUBMIT" NAME="Selection" VALUE="Validation"> <BR> <BR>

                         <INPUT TYPE="RESET" NAME="Reset" VALUE="Tout d&eacute;s&eacute;lectionner">

                         </FORM> </B> </CENTER>

                   </BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 10].

Le type HIDDEN :

Comme son nom l'indique, ce type d'attribut permet de cacher un champ de classe input ce qui signifie du point de vue graphique que rien n'apparaîtra dans le browser !

<INPUT TYPE="HIDDEN" NAME="nom_de_la_variable" VALUE="valeur_de_la_variable">

A quoi peut servir cette fonctionnalité ?

Dans un formulaire électronique, il arrive que les questions posées à un instant dépendent des réponses faites à l'instant précédent. On peut donc très bien imaginer la séquence suivante :

On génère un premier écran posant un certain nombre de questions.

A partir des réponses issues de ce premier ensemble de questions, on génère un deuxième écran comportant des questions complémentaires.

Comment cela fonctionnera-t-il dans des pages HTML ?

La première page s'exécute dans son cadre habituel : un fichier HTML standard définissant un formulaire avec appel d'un script CGI.

Lors de son exécution, ce script construit un nouveau formulaire, en tenant compte des réponses précédentes. On va donc exécuter avec ce nouveau formulaire un second script qui collectera de nouvelles données, mais devra aussi vraisemblablement faire connaître au script de traitement les premières données collectées. Ce premier jeu de données acquis lors de l'exécution du premier script est passé au second script à l'aide de champs input avec l'attribut hidden.

Tout se passera comme si le second formulaire faisait aussi l'acquisition des données du premier formulaire.

Nous ne pourrons pas montrer d'exemple avec l'attribut HIDDEN car, c'est un travail relativement simple.

Nous allons résumer cette leçon ci-après :

Le formulaire se décrit entre les balises <FORM> et </FORM>.

La balise <FORM> sera complétée au minimum par deux attributs suivants :

METHOD, prenant la valeur POST ou la valeur GET, définit le mode de transfert des données vers le script CGI.

ACTION qui définit l'URL d'un programme (script) chargé de traiter les données acquises depuis le formulaire.

Les propriétés de l'objet FORM sont :

action - URL CGI ou pseudo-protocole associé au formulaire.

method - GET ou POST (transfert des données au CGI).

target - fenêtre de destination.

enctype - encodage Mine des données.

elements - accès aux composants du formulaire.

La méthode de l'objet FORM est submit() qui déclenche la soumission (appelle le CGI avec les données collectées).

L'événement de l'objet FORM est onSubmit qui apparaît au moment de la soumission du formulaire.

La balise <INPUT> sert à définir des champs pour entrer un texte et des boutons permettant de choisir des options.

L'attribut TYPE, associé à la balise <INPUT> permet le choix de l'élément d'entrée.

Le type TEXT permet de collecter du texte alphanumérique.

Propriétés de l'objet TEXT :

name - nom attribué à la balise.

type - égal au type de la balise (text dans ce cas).

value - valeur saisie ou codée dans le HTML.

defaultValue - valeur attribuée par défaut dans le code HTML.

Méthode de l'objet TEXT :

focus() - amène le curseur dans le champ.

blur() - force le curseur hors du champ.

select() - sélectionne le contenu du champ.

Les événements de l'objet TEXT sont :

onChange - apparaît à la modification du champ de saisie.

Onfocus - apparaît à la prise du focus.

onBlur - apparaît à la perte du focus.

onSelect - apparaît lorsqu'on sélectionne tout ou partie du champ.

Le type SUBMIT déclenche l'envoi du formulaire vers le srcipt.

Propriétés de l'objet SUBMIT :

name, type, value - identiques à l'objet TEXT.

La méthode de l'objet SUBMIT est submit() qui déclenche la soumission.

L'événement de l'objet SUBMIT est onClick qui apparaît lors du clic sur le bouton.

Le type RESET permet d'effacer les données déjà entrées.

name, type, value - identiques à l'objet TEXT.

La méthode de l'objet RESET est click(), identique au clic que ferait l'utilisateur (clic programme)

L'événement de l'objet RESET est onClick qui apparaît lors du clic sur le bouton.

Le type PASSWORD permet de saisir un mot de passe de façon confidentielle.

Ses propriétés, méthodes et événement sont identiques à l'objet TEXT

Le type CHECKBOX permet de faire un bloc de boutons permettant un choix multiple d'options (fonction logique AND).

Le type RADIO permet de faire un bloc de boutons permettant un choix exclusif parmi plusieurs options (fonction logique ou exclusif).

Propriétés des objets CHECKBOX et RADIO :

name, type, value - identiques à l'objet TEXT.

checked - retourne true si la case est cochée.

defaultChecked - retourne true si c'est la case cochée par défaut.

index (radio seulement) - indice du bouton coché.

length (radio seulement) - nombre de boutons radio associés.

La méthode des objets CHECKBOX et RADIO est click(), identique au clic que ferait l'utilisateur (clic programme).

L'événement des objets CHECKBOX et RADIO est onClick qui apparaît lors du clic sur le bouton.

Le type HIDDEN sert à passer des données acquises dans un formulaire à un autre formulaire sans que rien n'apparaisse à l'écran.

Propriétés de l'objet HIDDEN :

name, type, value - identiques à l'objet TEXT.

La balise <SELECT> permet de générer des listes à choix simple (ou exclusif) ou à choix multiple (fonction AND). Elle se programme comme une liste où chacun des items est spécifié par la balise <OPTION>. De la présence de l'attribbut SIZE dépend de la présentation de la liste. Si la valeur donnée à l'attribut size est inférieure à 2 ou si l'attribut size est omis, la liste est interprétée comme un menu déroulant (pop-list). dans le cas contraire, elle s'affiche dans une fenêtre à ascenseur. La valeur donnée à l'attribut size donne alors le nombre de lignes visibles dans la fenêtre. L'option choix multiple résulte de la présence de l'attribut MULTIPLE.

Propriétés de l'objet SELECT :

name, type - identiques à l'objet TEXT ;

selectedIndex - index de la première ou de la seule option sélectionnée.

Méthode de l'objet SELECT :

blur, focus - identiques à l'objet TEXT.

Evénement de l'objet SELECT :

onChange, onFocus, onBlur - identiques à l'objet TEXT.

Propriétés de l'objet OPTION :

defaultSelected - a la valeur true si c'est option est sélectionnée par défaut.

selected - a la valeur true si l'option est sélectionnée.

text - texte associé à l'option.

value - valeur associée à l'option.

La balise <TEXTAREA> permet de créer une fenêtre avec ascenseurs horizontaux et verticaux dans laquelle on pourra saisir du texte. La valeur donnée aux attributs ROWS (lignes) et COLS (colonnes) délimite la taille de cette fenêtre.

Les propriétés, méthodes et options de l'objet TEXTAREA sont celles de l'objet TEXT.

RAPPELS :

Le script doit connaître l'élément du formulaire duquel provient une donnée. L'attribut NAME permet d'affecter un identificateur à chacun des éléments du formulaire.

L'attribut VALUE permet :

De spécifier un texte à écrire sur les boutons RESET et SUBMIT (information visuelle).

De préremplir un champ TEXTAREA (information visuelle)

D'attribuer une valeur à l'option pour les boutons RADIO et CHECKBOX (information pour le script).

Fin de cette seizième leçon, la prochaine sera consacrée à la programmation CGI concernant le langage HTML.


Sommaire : Langage PHP avec leurs Programmes

Vu dans ... http://www.electronique-et-informatique.fr/Electronique-et-Informatique/PHP_et_Programmes/PHP_Programmes.php

Sommaire - Langage PHP avec leurs Programmes :

Sommaire - PHP et Programmation ; A noter : vous pouvez utiliser un bloc note pour faire tous vos essais
1. - Utilisation de PHP, Formulaire de Commande, Traitement et Incorporation de code PHP dans du Code HTML
1. 2. - Ajouts de Contenu Dynamique, Invocation de fonctions, Fonction Date, Accès aux Variables de formulaires
1. 3. - Opérateurs Arithmétiques, Opérateurs de Comparaison, Opérateurs Logiques, Opérateurs Bitwise, etc.
1. 4. - Utilisation des Opérateurs, Calcul des Totaux d'un Formulaire de Commande
1. 5. - Tests État des Variables, Structures Conditionnelles, Blocs de Code, Instructions else, elseif, switch, Boucles while
2. - Utilisation de "fopen()" pour ouvrir un fichier, Écriture "fwrite()" dans un fichier et fermeture "fclose()" du fichier
2. 1. - Ouverture d'un Fichier, en vue d'une Lecture fopen(), feof(), fgets(), fgetss(), fgetcsv(), reafile(), fpassthru() et file()
3. - Utilisation de Tableaux, Tableaux Indexés Numériquement, Tableaux Associatifs, Tableaux Multidimensionnels
3. 1 - Utilisation de la Fonction shuffle(), Chargement d'un Tableau à Partir de Fichiers, each(), current(), reset() ...
4. - Formulaire Intelligent de Saisie d'un Message, Mise en Forme des Chaînes, strtok(), substr(), strcmp() strcasecmp()
4. 1. - Localisation de Sous-chaînes dans des Chaînes, strstr(), strchr(), strrchr(), stristr(), strpos(), strrpos(), str_replace()
5. - Utilisation des Instructions require() et include(), Configuration Auto_prepend_file et Auto_append_file
5. 1. - Utilisation de Fonctions et Structure de Base, Attribution d'un Nom à une Fonction ainsi que les Paramètres
5. 2. - Passer par Référence Contre Passer par Valeur, Sortie Forcée d'une Fonction et Renvoi de Valeurs par des Fonctions
6. - Programmation Orientée Objets, Polymorphisme, Héritage, Création et Structure de Classes, Constructeurs, Instanciation
6. 1. - Programmation Orientée Objets (2ème partie) et Implémentation d'une Classe pour créer un Site fictif
7. - Conception de votre Base de Données, Tableaux, Colonnes, Lignes, Valeurs, Clés, Schémas et relations
7. 1. - Conception et Création de la Base de Données Web, Utilisateurs et Privilèges avec leurs Commandes SQL
7. 2. - Créations de la Base de Données ainsi que les Tableaux et Configuration d'un Utilisateur (3ème partie)
7. 3. - Identificateurs MySQL, Types de Données des Colonnes et Numériques, Dates Heures (4ème partie)
8. - Travailler avec votre Base de Données MySQL et Insertion de Données dans la Base de Données (1ère partie)
8. 1. - Lire et Récupérer des Données dans la Base de Données, Fusion simple de deux Tableaux, Les Alias
8. 2. - Récupérer, Groupement et Agrégation des Données, Choisir les Lignes à Renvoyer, Mise à Jour des Enregistrements
9. - Accéder à votre Base de Données MySQL à partir du Web, Principales étapes pour Interroger une Base de Données
9. 1. - Ajouter des Informations dans la Base de Données, Autres Fonctions Utiles de PHP / MySQL (2ème partie)
10. - Implémenter une Authentification avec PHP et MySQL, Enregistrement et Cryptage des Mots de Passe
11. - Téléchargement de Fichiers vers le Serveur avec PHP, Uploader, Introduction, Écriture du code PHP (1ère partie)
11. 1. - Lecture, Création et Suppression du Contenu de Dossiers, Obtention d'Informations sur les Fichiers
12. - Génération et Création d'Images, Image-Canevas, Dessin ou Impression de Texte dans une Image (1ère partie)
12. 1. - Représentation Graphique de Données Numériques, Création et de Manipulation d'Image, Sondage (2ème partie)
13. - Authentifier les Utilisateurs et Personnaliser le Site, Implémentation de la Base de Données Bookmarks (1ère partie)
13. 1. - Implémentation de Base du Site et l'Authentification des Utilisateurs, Enregistrement des Users (2ème partie)
13. 2. - Implémentation d'Ouverture et de Fermeture de Session, Mot de Passe (3ème partie)
13. 3. - Implémentation de l'Enregistrement et de la Lecture et Suppression des URLs Signets (4ème partie)
14. - Implémenter un Caddie, Implémenter un Catalogue, Paiement et Conserver une Trace des Achats (1ère partie)
14. 1. - Implémentation de la Base de Données et du Catalogue en Ligne, Listes des Catégories et Livres (2ème partie)
14. 2. - Implémentation et Afficher le Caddie, Ajouter et Enregistrer des Articles, Sortir du Magasin (3ème partie)
14. 3. - Implémentation du Paiement Caddie et Implémentation d'une Interface d'Administration (4ème partie)


Accéder à votre Base de données à Partir du Web

Accéder à votre base de données MySQL à partir du Web (1ère partie) :

Quelques rappels :

Auparavant, lorsque nous travaillions avec PHP, nous nous servions d'un fichier brut pour enregistrer et récupérer nos données. Lorsque nous avons mentionné cette approche de la deuxième leçon, en cliquant ici, nous avons également dit que les systèmes de bases de données relationnelles rendent ces deux tâches (enregistrement et récupération des données) à la fois plus simples, plus sûres et plus efficaces dans le cadre d'une application Web. Maintenant que nous sommes capable de nous servir de MySQL pour créer des bases de données, nous pouvons commencer à connecter cette base de données à une interface Web.

Dans cette leçon, nous verrons comment accéder à la base de données de chez Jean-Pierre à partir du Web, en utilisant PHP. Vous apprendrez à lire et à écrire dans cette base de données, et à filtrer les données d'entrée qui peuvent poser problème.

Fonctionnement des architectures de bases de données Web :

Dans la leçon précédente, en cliquant ici, nous avons mis en évidence le fonctionnement des architectures de bases de données Web. A titre de rappel, voici les principales étapes de ce processus :

  1. Le navigateur Web d'un utilisateur envoie une requête HTTP correspondant à une page particulière. Par exemple, l'utilisateur peut avoir demandé de chercher tous les livres écrits par Michaël-Pierre ROBERT, du site de chez Jean-Pierre, à l'aide d'un formulaire HTML. La page de recherche des résultats est appelée Resultats_Serveur.php.

  2. Le serveur Web reçoit la requête concernant Resultats_Serveur.php, récupère le fichier correspondant, et le passe au moteur PHP afin qu'il y soit traité.

  3. Le moteur PHP commence à analyser le script. A l'intérieur de ce script se trouve une commande permettant de se connecter à la base de données, et d'exécuter une requête (c'est-à-dire de rechercher les livres). PHP ouvre ensuite une connexion vers le serveur MySQL, et envoie la requête appropriée.

  4. Le serveur MySQL reçoit la requête en provenance de la base de données, la traite, et renvoie les résultats obtenus (une liste de livres) au moteur PHP.

  5. Le moteur PHP finit l'exécution du script, qui consiste généralement à formater les résultats de la requête d'une manière agréable à lire, en HTML. Le fichier HTML obtenu est alors renvoyé au serveur Web.

  6. Le serveur Web renvoie à son tour le fichier HTML au navigateur, qui l'affiche pour que l'utilisateur puisse voir la liste de livres qu'il a demandée.

Maintenant que nous possédons une base de données MySQL, nous pouvons écrire le code PHP permettant d'exécuter les étapes précédentes. Nous commencerons par le formulaire de recherche. Il s'agit d'un formulaire en HTML classique. Le code de ce formulaire se trouve dans le Listing 1.

Listing 1. - Catalogue_de_Recherche.html - La page de recherche dans la base de données de chez Jean-Pierre :

Le formulaire HTML est très simple. Sa sortie est présentée à la figure 1.

Le script invoqué lorsque l'utilisateur clique sur le bouton Recherchez est Resultats_Serveur.php. Vous trouverez le code correspondant au Listing 2. Tout au long de cette leçon, nous allons expliquer le but et le fonctionnement de ce script.

Listing 2. - Resultats_Serveur.php - Le script qui récupère les résultats de notre base de données MySQL et qui les formate pour les afficher correctement :

La figure 2 illustre les résultats de ce script :

A noter : pour visualiser correctement l'aperçu et voir le bon déroulement du programme, vous pouvez insérer ces noms dans le champ de : "entrez votre recherche" comme ci-après : Daniel ROBERT, Julie DUPONDRA, Jennifer-Josiane LEDUC, Michelle-Patty MONPARNA. Mais vous aurez l'occasion d'enregistrer votre pseudo, [exemple 2], en bas de cette page de la première ou de la deuxième partie de cette leçon.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Principales étapes pour interroger une base de données à partir du Web :

Dans tous les scripts utlisés pour accéder à une base de données à partir du Web, il faut respecter les étapes suivantes :

  1. Vérifier et filtrer les données fournies pas l'utilisateur.

  2. Etablir une connexion vers la base de données appropriée.

  3. Interroger la base de données.

  4. Récupérer les résultats.

  5. Présenter les résultats à l'utilisateur

Ces étapes ont été respectées dans le script Resultats_Serveur.php, et nous allons maintenant les étudier une par une.

Vérifier et filtrer les données saisies par l'utilisateur :

Nous commençons notre script, en supprimant tous les espaces que l'utilisateur peut avoir saisis par inadvertance au début ou à la fin de ses données. Pour cela, nous appliquons la fonction trim() à $Terme_de_recherche.

    $Terme_de_recherche = trim($Terme_de_recherche) ;

La prochaine étape consiste à vérifier que l'utilisateur a bien entré une expression à chercher, et un type de recherche. Vous remarquerez que nous effectuons cette vérification après avoir supprimé les espaces blancs aux deux extrémités de $Terme_de_recherche. Si nous avions inversé ces deux opérations, nous ne pourrions pas détecter le cas où l'utilisateur a saisi uniquement des espaces :

    if (!$Type_de_Recherche || !$Terme_de_recherche)

    {

       echo "<font color = '#005555'> <b> Vous n'avez pas saisi tous les d&eacute;tails requis ! Veuillez recommencer, merci ! </b> </font>" ;

    exit ;

    }

Vous remarquerez aussi que nous vérifions la variable $Type_de_Recherche, bien qu'elle provienne dans notre cas d'une instruction HTML SELECT. Vous vous demandez peut-être pourquoi nous prenons la peine de vérifier des variables qui doivent être remplies automatiquement. Il est très important de se rappeler qu'il peut exister plusieurs interfaces à votre base de données. Par exemple, Amazon possède plusieurs filiales qui se servent de la même interface de recherche. De plus, il est important de filtrer les données, en cas de problème de sécurité.

Il faut savoir que lorsque vous travaillez avec des données saisies par les utilisateurs. Vous devez filtrer ces données pour supprimer tous les caractères de contrôle. Rappelez-vous que les fonctions addslashes() et stripslashes() que nous avons vues à la quatrième leçon, en cliquant ici. Vous devez vous servir de addslashes() lorsque vous envoyez les données des utilisateurs à une base de données comme MySQL, et de stripslashes() pour renvoyer les résultats de la base de données à vos utilisateurs.

Dans notre cas, nous nous servons de addslashes() sur l'expression recherchée.

    $Terme_de_recherche = addslashes($Terme_de_recherche) ;

Nous nous servons également de stripslashes() sur les données provenant de la base de données. En effet, aucune des données que nous avons entrées manuellement dans la base de données ne contient de slashs (/), ni aucun caractère de contrôle. L'appel de la fonction stripslashes() n'a donc en principe aucun effet. Comme nous construisons une interface Web pour la base de données, il y a de fortes chances que nous soyons amené à y ajouter de nouveaux livres, et les données saisies peuvent contenir ces caractères. Lorsque nous les ajoutons à la base de données, nous appelons addslashes(), ce qui signifie que nous devons appeler stripslashes() quand nous récupérons les données. Il s'agit surtout d'une bonne habitude à prendre.

Nous nous servons de la fonction htmlspecialchars() pour coder les caractères qui ont une signification particulière en HTML. Nos données de test actuelles ne contiennent aucun de ces caractères (&, <, >, ou "), mais il existe plusieurs titres de livres qui contiennent le symbole &. Grâce à cette fonction, nous pouvons éliminer de futures erreurs.

    echo htmlspecialchars(stripslashes($row["titre"])) ;

Établissement de la connexion :

Dans notre script, les lignes suivantes permettent d'établir la connexion au serveur MySQL :

    <?php

     echo "<BR> <font face = 'Arial' size = '3'>" ; // Permet d'améliorer l'affichage des caractères en cas d'erreur

     // Connexion base de données MYSQL

    $connect = mysql_connect('localhost', 'root', '') ; // Connexion au serveur local EasyPHP, sinon, pour les serveurs à distant, il faudra changer les paramètres de cette connexion

    if (!$connect)

    {

      die('Impossible de se connecter au serveur MySQL') ;

      exit ;

    }

    mysql_select_db('books', $connect) ; // Base de données sélectionnées pour la table "books"

    mysql_query("SET NAMES 'UTF8'"); // Permet de se connecter en UTF8 concernant les caractères accentués

    ?>

Nous nous sommes servi de la fonction mysql_connect() pour nous connecter à la base de données. Nous mettons le prototype de cette fonction :

    int mysql_pconnect( [string host [:port] [:/socketpath] ] ,

                        [string user] , [string password] ) ;

D'une manière générale, il faut lui fournir le nom de l'hôte qui héberge le serveur MySQL, le nom d'utilisateur permettant de se logger, et le mot de passe correspondant à cet utilisateur. Tous ces arguments sont optionnels, et si vous ne les spécifiez pas, la fonction se sert des valeurs par défaut : localhost pour l'hôte, le nom d'utilisateur sous lequel PHP est exécuté, et aucun mot de passe dans le cas du serveur local EasyPHP. Sinon, chaque serveur à distant, il faudra lui fournir un mot de passe ainsi que le nom de l'utilisateur que le fournisseur d'accès Internet (FAI) vous a transmis.

Cette fonction renvoie un identificateur de lien vers votre base de données MySQL, en cas de succès (qu'il faut conserver, puisque nous en aurons besoin par la suite), ou false en cas d'échec. Il est intéressant de tester le résultat de cette fonction, puisque le reste du code ne fonctionnera pas si la connexion n'a pas pu être établie. Nous nous sommes servi du code suivant :

    if (!$connect)

    {

      die('Impossible de se connecter au serveur MySQL') ;

      exit ;

    }

Listing 3. - Connexion_MySQL.php - Le script qui vous permet de vous connecter au serveur MySQL (pour serveur à distant, il faudra changer certains paramètres) :

Une autre fonction, très semblable à mysql_pconnect() est mysql_connect(). La différence avec mysql_pconnect() et que cette fonction renvoie une "connexion persistante" vers la base de données.

Une connexion normale vers la base de données est fermée lorsque l'exécution du script est terminée, ou lorsque le script appelle mysql_close(). Une connexion persistante reste ouverte après la fin de l'exécution du script, et ne peut pas être fermée par la fonction mysql_close().

Vous vous demandez peut-être à quoi servent les connexions persistantes. La réponse est assez simple : la connexion à une base de données prend un certain temps. Lorsque mysql_pconnect() est invoquée, elle vérifie automatiquement s'il existe une connexion persitante, avant de se connecter à la base de données. Si c'est le cas, elle se sert de la connexion déjà établie, au lieu d'en ouvrir une nouvelle, ce qui permet de gagner un peu de temps, et de soulager le serveur.

Il est également intéressant de remarquer que les connexions persistantes deviennent des connexions normales si vous exécutez votre code PHP sous la forme d'un script CGI : chaque appel à un script PHP démarre une nouvelle instance de PHP et la referme après l'exécution du script. Ce mécanisme ferme aussi toutes les connexions persistantes ouvertes.

N'oubliez pas qu'il existe une limite sur le nombre de connexions MySQL qui peuvent exister simultanément. Le paramètre MySQL max_connections détermine cette limite. L'intérêt de ce paramètre et du paramètre Apache "MaxClients" associé et de permettre au serveur de rejeter les nouvelles requêtes de connexion lorsqu'un ordinateur commence à être surcharger, ou lors d'un plantage.

Bien sûr, vous pouvez modifier la valeur par défaut de ces deux paramètres, en modifiant le fichier de configuration. Pour modifier MaxClients dans Apache, éditez le fichier httpd.conf de votre système. Pour changer le paramètre max_connections de MySQL, modifiez le fichier my.conf.

Si vous utilisez des connexions persistantes et que presque toutes les pages de votre site aient besoin d'accéder à une base de données, vous ouvrirez une connexion persistante pour chaque processus Apache. Cela peut poser problème si vous avez conservé les paramètres par défaut. En effet, Apache autorise par défaut 150 connexions (environ), mais MySQL n'en autorise que 100. Lorsque votre site sera très fréquenté, il se peut que vous manquiez de connexions. En fonction des caractéristiques de votre plate-forme, vous devez ajuster ces paramètres pour que chaque processus du serveur Web puisse ouvrir une connexion.

Choisir la base de données à utiliser :

Vous vous rappelez sans doute que lorsque nous utilisons MySQL à partir de la ligne de commande, nous devons lui indiquer la base de données que nous avons l'intention d'utiliser, avec une commande comme celle-ci :

    use books ; // Sur certains serveurs locaux : erreur 1044 - Accès refusé pour l'utilisateur à la base de données 'books'

Attention : sur certains serveurs à distant, USE ne peut fonctionner pour cause que ce paramètre peut être désactivé par le FAI (Fournisseur d'Accès Internet).

La création d'une base de données particulière par défaut au moyen de l'instruction USE ne vous empêche pas d'accéder aux tables d'autres bases de données.

Cette étape est aussi nécessaire lorsque nous nous connectons à partir du Web. Nous pouvons nous servir de PHP, grâce à un appel de la fonction mysql_select_db(), comme ci-après :

    mysql_select_db('books', $connect) ; // Base de données sélectionnée pour la table "books"

Voici le prototype de la fonction mysql_select_db() :

    int mysql_select_db(string database, [int database_connection] ) ;

Cette fonction indique que nous souhaitons utiliser la base de données appelée database. Il est également possible de spécifier optionnellement le lien vers la base de données, lien sur lequel vous souhaitez effectuer cette opération (dans ce cas, $connect), mais si vous n'en spécifiez aucun, le dernier lien ouvert sera utilisé. Si aucun lien n'a été ouvert, le lien par défaut sera ouvert, comme si vous aviez appelé mysql_connect().

Interroger la base de données :

Pour effectuer réellement la requête, vous pouvez utiliser la fonction mysql_query(). Cependant, avant d'appeler cette fonction, il faut mieux configurer la requête que vous voulez exécuter :

    $req = mysql_query("SELECT * FROM les_livres WHERE auteur = '$Terme_de_recherche'") ;

    $query = "$req" . $Type_de_Recherche . "like '%" . $Terme_de_recherche . "%'" ;

Dans ce cas, nous cherchons les données saisies par l'utilisateur ($Terme_de_recherche) dans le champ spécifié par l'utilisateur ($Type_de_Recherche. Vous remarquerez que nous avons spécifié l'opérateur like au lieu de egal. Il faut généralement mieux être assez tolérant pour les recherches dans les bases de données.

Il est important de bien comprendre que les requêtes que vous envoyez à MySQL n'ont pas besoin de se terminer par un point-virgule, contrairement aux requêtes que vous saisissez dans le moniteur de MySQL.

La fonction mysql_query() possède le prototype suivant :

    int mysql_query(string query, [int database_connection] ) ;

Cette fonction reçoit la requête que vous souhaitez exécuter, et optionnellement le lien vers la base de données (ici, $connect). Si ce lien n'est pas spécifié, la fonction récupère le dernier lien ouvert. S'il n'y en a aucun, la fonction ouvre le lien par défaut, comme si vous aviez appelé mysql_connect().

Vous pouvez aussi utiliser la fonction mysql_db_query(), dont voici le prototype :

    int mysql_db_query(string database, string query, [int database_connection] ) ;

Cette fonction permet de spécifier la base de données que vous souhaitez interroger. Il s'agit donc d'une combinaison des fonctions mysql_select_db() et mysql_query().

Ces deux fonctions renvoient un identificateur de résultat (qui permet de récupérer les résultats des requêtes), en cas de succès, et false en cas d'échec. Il convient d'enregistrer cet identificateur (dans notre cas, nous l'enregistrons dans $req), pour pouvoir s'en servir par la suite.

Récupérer les résultats de la requête :

Il existe plusieurs fonctions permettant de récupérer ces résultats à partir de l'identificateur. Ce dernier sert de clé pour accéder à zéro, une ou plusieurs lignes renvoyées par la requête.

Dans notre exemple, nous nous servons de deux de ces fonctions : mysql_num_rows() et mysql_fetch_array().

La fonction mysql_num_rows() fournit le nombre de lignes renvoyées par la requête. Il faut lui passer l'identificateur de résultat, comme ceci :

    $num_results = mysql_num_rows($req) ;

Cette information est intéressante : si nous avons l'intention de traiter ou d'afficher les résultats par la suite, nous pouvons ainsi savoir combien il y en a, pour les traiter à tour de rôle :

    for ($i = 0 ; $i < $num_results ; $i++)

    {

    // Traitement des résultats ...

    }

Pendant chaque itération de cette boucle, nous appelons mysql_fetch_array(). Cette boucle n'est pas exécutée si aucune ligne n'est renvoyée. Cette fonction prend en argument chaque ligne renvoyée et renvoie à son tour cette même ligne sous la forme d'un tableau associatif, chaque clé étant transformée en nom d'attribut et chaque valeur étant associée à la valeur correspondante dans le tableau :

    $row = mysql_fetch_array($req) ;

A partir du tableau associatif $row, nous pouvons parcourir chaque champ et l'afficher d'une manière appropriée, comme ceci :

    echo "<BR/>&nbsp;&nbsp;&nbsp;&nbsp;Prix : &nbsp;" ;

    echo htmlspecialchars(stripslashes($row["prix"])) ;

Comme nous l'avons déjà vu, nous nous servons de stripslashes() pour filtrer les valeurs avant de les afficher.

Il existe plusieurs manières de récupérer les résultats à partir de l'identificateur de résultats. Au lieu de passer par un tableau associatif, nous pouvons placer les résultats dans un tableau d'énumération avec mysql_fetch_row(), comme ci-après :

    $row = mysql_fetch_row($req) ;

Les valeurs des attributs sont listées dans les valeurs du tableau $row[0], $row[1], $row[2), etc.

Il est également possible de placer une ligne entière dans un objet avec la fonction mysql_fetch_objet() :

    $row = mysql_fetch_object($req) ;

Vous pouvez alors accéder à chacun des attributs avec $row->titre, $row->auteur, etc.

Chacune de ces approches lit une ligne lors de chaque opération. Une autre approche consiste à lire un champ chaque fois, en utilisant mysql_result(). Pour cela, vous devez spécifier le numéro de la ligne (compris entre 0 et le nombre total de lignes - 1), ainsi que le nom du champ. Par exemple :

    $row = mysql_result($req, $i, "titre") ;

Vous pouvez spécifier le nom du champ sous la forme d'une chaîne (soit au format "les_livres", ou au format "books . les_livres"), ou sous la forme d'un nombre (comme dans mysql_fetch_row()). Il ne faut pas mélanger l'utilisation de mysql_result() avec celle des autres fonctions de lecture.

Les fonctions de lecture par lignes sont bien plus efficaces que mysql_result(), c'est pourquoi ces fonctions sont plus souvent utilisées.

Déconnexion de la base de données :

Vous pouvez vous servir de mysql_close :

    mysql_close($connect) ;

Pour fermer une connexion non persistante à une base de données. Ce n'est pas strictement nécessaire, parce que, de toute manière, les connexions sont fermées lorsque le script a terminé son exécution.

Nous terminons ainsi ce premier chapitre de cette leçon et nous verrons dans le prochain, Comment Ajouter des informations dans la base de données de chez Jean-Pierre (sur le Web).


Authentification des utilisateurs de l'espace membre

Authentifier les Utilisateurs et personnaliser le site (1ère partie) :

Personnalisation de l'utilisateur :

Dans ce projet, nous demandons aux utilisateurs de s'enregistrer sur notre site Web de chez Jean-Pierre. Après cette étape, nous pouvons savoir ce qui les intéresse et afficher le contenu approprié. C'est ce que l'on appelle la personnalisation en fonction de l'utilisateur.

Ce projet permet aux utilisateurs d'enregistrer un ensemble de liens vers leurs sites Web favoris, et suggère d'autres liens qui peuvent les intéresser, en fonction des sites qu'ils ont déjà visités. D'une manière plus générale, la personnalisation peut être utilisée dans n'importe quelle application Web pour afficher des informations plus ciblées, dans un format personnalisé.

Dans ce projet, et dans les autres qui suivront, nous commencerons par examiner un cahier des charges semblable à ceux que vous pourriez obtenir d'éventuels clients. Nous transformerons ensuite les différents éléments de ce cahier des charges, en un ensemble de composants, nous mettrons en place une architecture permettant d'interconnecter ces composants, et nous implémenterons chacun de ces composants.

Pour ce projet, nous implémenterons les fonctionnalités des utilisateurs :

  • Authentification et ouverture de session des utilisateurs ;

  • Gestion des mots de passe ;

  • Enregistrement des préférences des utilisateurs ;

  • Personnalisation du contenu ;

  • Suggestion de sites intéressants, en fonction des informations que nous possédons sur un utilisateur.

Le problème :

Notre système doit permettre aux utilisateurs de se logger et d'enregistrer leurs sites favoris, et il doit suggérer quelques sites qui pourraient les intéresser, en fonction de leurs préférences personnelles.

Ces spécifications peuvent être classées en trois catégories.

Tout d'abord, nous devons pouvoir identifier les utilisateurs. Il nous faut également un système pour les authentifier.

Ensuite, nous devons pouvoir enregistrer des liens vers leurs sites favoris. Les utilisateurs doivent être capables d'ajouter et de supprimer ces liens.

Enfin, il faut être en mesure de recommander des sites qui peuvent intéresser les utilisateurs, en fonction des informations que nous possédons déjà.

Les composants :

Maintenant que nous connaissons les spécifications de notre système, nous pouvons choisir une architecture et un ensemble de composants. Essayons de passer en revue quelques solutions à chacune des spécifications que nous venons de voir.

Identification des utilisateurs et personnalisation du site :

Il existe plusieurs techniques permettant d'authentifier les utilisateurs, ainsi que nous l'avons déjà vu dans les leçons précédentes. Comme nous souhaitons rattacher certaines informations à chaque utilisateur, nous devons enregistrer les noms des utilisateurs et les mots de passe dans une base de données MySQL, et implémenter une méthode d'authentification à partir de ces informations.

Si nous devons permettre aux utilisateurs de se logger, en saisissant un nom d'utilisateur et un mot de passe ainsi que leur E-Mail, nous avons besoin des composants suivants :

  • Les utilisateurs doivent être capables d'enregistrer leur nom d'utilisateur et leur mot de passe y compris leur E-Mail. Nous devons implémenter certaines restrictions portant sur la longueur et le format de ces informations. Il faut enregistrer les mots de passe dans un format crypté, pour des raisons évidentes de sécurité.

  • Les utilisateurs doivent être capables de se logger avec les détails qu'ils ont fournis lors de leur enregistrement.

  • Les utilisateurs doivent être capables de fermer leur session lorsqu'ils ont fini d'utiliser notre site. Cela n'est pas particulièrement important si les utilisateurs accèdent à notre site depuis leur PC personnel, mais cet aspect de la sécurité est essentiel s'ils accèdent à notre site depuis un PC partagé.

  • Le site doit être capable de vérifier si un utilisateur est loggé ou non, et d'accéder aux données correspondant à un utilisateur loggé.

  • Les utilisateurs doivent ête capables de modifier leur mot de passe, pour améliorer la sécurité générale du site.

  • Les utilisateurs peuvent oublier occasionnellement leur mot de passe. Ils doivent être capables de se débrouiller sans notre assistance. Généralement, on propose aux utilisateurs de leur envoyer leur mot de passe à l'adresse E-Mail qu'ils ont fournie lors de leur enregistrement. Cela signifie que nous devons enregistrer cette adresse E-Mail au moment de leur enregistrement. Comme nous enregistrons les mots de passe dans un format crypté et qu'il est impossible de le décrypter pour retrouver le mot de passe d'origine, il faut en fait générer un nouveau mot de passe, l'activer, et le transmettre à l'utilisateur par E-Mail.

Nous allons écrire des fonctions pour chacune de ces fonctionnalités. La plupart d'entre elles, seront réutilisables dans d'autres projets, ou réutilisables moyennant quelques modifications.

Enregistrer les liens vers les sites favoris :

Pour enregistrer les liens d'un utilisateur, nous devons aménager un espace particulier dans notre base de données MySQL. Nous aurons besoin des fonctionnalités suivantes :

  • Les utilisateurs doivent être capables d'afficher leurs liens.

  • Les utilisateurs doivent être capables d'ajouter de nouveaux liens. Il convient de vérifier qu'il s'agit bien d'URL valides.

  • Les utilisateurs doivent être capables de supprimer leurs liens.

Une fois encore, nous sommes en mesure d'écrire des fonctions pour chacune de ces fonctionnalités.

Sites recommandés :

Il existe plusieurs techniques permettant de générer une liste de sites recommandés pour un utilisateur donné. Nous pouvons nous contenter d'afficher les sites les plus populaires, ou les plus populaires dans un domaine particulier. Pour ce projet, nous allons implémenter un système de suggestion qui cherche les sites favoris communs à plusieurs utilisateurs, et qui les échange entre ces utilisateurs. Pour éviter d'échanger des sites un peu trop personnels, nous nous contentons d'afficher les sites enregistrés par plusieurs autres utilisateurs.

Nous pouvons une fois encore écrire une fonction pour implémenter cette fonctionnalité.

Présentation de la solution :

Après avoir griffonné quelques dessins, nous avons retenu l'architecture présentée à la figure 1.

Nous allons construire un module pour chaque composant de ce diagramme. Certains d'entre eux pourront être implémentés avec un seul script, mais il en faudra deux pour certains autres. Nous allons également mettre en place des bibliothèques de fonctions pour :

  • L'authentification des utilisateurs.

  • L'enregistrement et l'affichage des sites favoris.

  • La validation des données.

  • Les connexions à la base de données.

  • La sortie dans le navigateur. Toutes les fonctions de génération de code HTML se trouveront dans cette bibliothèque, pour que la présentation visuelle reste cohérente au travers de tout le site.

Nous devons également mettre en place une base de données pour ce système.

Nous allons ensuite étudier, en détail l'implémentation de chaque fonctionnalité. Mais vous trouverez l'intégralité de cette application au cours de nos leçons dans le tableau 1, un résumé contenant tous les fichiers concernés :

Tableau 1. - Les fichiers de l'application "Bookmarks" en PHP (en respectant la casse) :
Nom du fichier | Description
add_bm_form.php | Formulaire permettant d'ajouter de nouveaux sites favoris.
add_bms.php | Script pour ajouter de nouveaux sites dans la base de données.
Bookmarks.sql | Instructions SQL permettant de créer la base de données Bookmarks du 1er tableau (membre_signets) et (membre_url_signets)
Bienvenue.php | Comme son nom l'indique, Bienvenue à l'ensemble des pages Sites avec les URLs.
Bienvenue_aux_Jeux.php | Comme son nom l'indique, Bienvenue à l'ensemble des Jeux.
bookmark_fns.php | Un ensemble de déclarations à inclure pour l'application de notre projet.
change_passwd.php | Script permettant de modifier le mot de passe de l'utilisateur dans la base de données.
change_passwd_form.php | Formulaire à remplir pour modifier le mot de passe actuel.
config.php | Configuration de la connexion de la base de données de certains programmes, voir le fichier texte ci-joint.
connexion.php | Comme son nom l'indique, c'est pour se connecter à l'ensemble du site.
Control_Session.php | Comme son nom l'indique, c'est pour contrôler toutes les Sessions afin que l'utilisateur puisse naviguer sur le site.
Courses_Automobiles.php | Comme son nom l'indique, jeux de courses automobiles. (En surplus du programme).
data_valid_fns.php | Fonctions permettant de valider les données saisies par l'utilisateur.
db_fns.php | Fonctions pour se connecter à la base de données.
delete_bms.php | Script permettant de supprimer les sites sélectionnés dans la liste de l'utilisateur.
edit_infos.php | Script permettant de changer les mots de passe ainsi que les informations de l'utilisateur.
forgot_form.php | Formulaire à remplir par les utilisateurs qui ont oublié leur mot de passe afin de pouvoir les mettre à jour.
forgot_passwd.php | Script pour réinitialiser les mots de passe oubliés, fichier en surplus pour ceux qu'ils veulent modifier ce dernier
index.php | Page principale pour se connecter. C'est un sommaire.
Jeux_Arcades.php | Comme son nom l'indique, jeux d'arcades. (En surplus du programme).
Jeux_de_Labyrinthe_3.php | Comme son nom l'indique, jeux de labyrinthe. (En surplus du programme).
Jeux_de_Strategie.php | Comme son nom l'indique, jeux de stratégie. (En surplus du programme).
Lecture_Signets.php | Script permettant de lire les signets ou les URLs avec leurs hyperliens de tous les utilisateurs.
Lisez_moi.txt | Fichier permettant d'expliquer les connexions entre la base de données MySQL et PHP
login.php | Page d'accueil avec un formulaire de login pour le système, Identique au fichier de connexion . (En surplus).
logout.php | Script pour fermer la session d'un utilisateur.
member.php | Page principale d'un utilisateur, qui contient tous ses sites favoris.
Menu.php | Comme son nom l'indique, ce fichier permet d'afficher les menus déroulant sur certaines pages.
output_fns.php | Fonctions pour formater la sortie en HTML.
profile.php | Script permettant de visualiser les profils des utilisateurs.
recommend.php | Script pour générer des sites, en fonction des utilisateurs qui ont les mêmes goûts.
register_form.php | Formulaire permettant aux utilisateurs de s'enregistrer auprès du système. (En surplus du programme)
register_new.php | Script qui traite l'enregistrement des nouveaux utilisateurs. (En surplus du programme).
sign_up.php | Identique au Script qui traite l'enregistrement des nouveaux utilisateurs. (Voir register_new.php).
url_fns.php | Fonctions pour ajouter et supprimer des sites, et effectuer des recommandations. Identique au fichier recommend.php.
user_auth_fns.php | Fonctions implémentant l'authentification des utilisateurs. (En surplus du programme).
users.php | Script permettant de visualiser les noms des utilisateurs.
users.sql | Instructions SQL permettant de créer la base de données Bookmarks du 2ème tableau (membre_utilisateurs).
logo.png | Logo de l'espace membre.
francophone1.gif | Notre logo du bureau d'étude que vous pouvez remplacer par le vôtre.
style.css | Feuille de style à l'espace Membre que vous pouvez modifier selon votre guise.
default | Répertoire pour la feuille de style et autres.
images | Répertoire images.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1]. Nous allons voir tous ces fichiers en détail.

Pour télécharger ces fichiers, en cliquant ici.

Nous commencerons par implémenter la base de données MySQL de cette application, puisqu'elle est nécessaire à toutes les autres fonctionnalités.

Nous présenterons ensuite le code dans l'ordre où il a été écrit, en commençant par la page d'accueil, avant de nous intéresser à l'authentification des utilisateurs, à l'enregistrement et à la lecture des liens vers les sites favoris, et en terminant par les recommandations. Cet ordre est assez logique, puisqu'il respecte les dépendances existant entre les différents modules.

Attention : Pour que le code de ce projet fonctionne tel qu'il est écrit, vous devez activer les guillemets magiques. Si vous ne l'avez pas encore fait, vous devrez filtrer les données qui doivent être insérées dans la base de données avec addslashes(), et vous servir de stripslashes() pour récupérer ces données. Nous avons choisi la première approche, qui est beaucoup plus simple.

Implémentation de la base de données :

Le schéma de la base de données "Bookmarks" est assez simple. Nous devons enregistrer les utilisateurs et leur adresse E-Mail, ainsi que leur mot de passe. Nous devons également enregistrer les URLs de leurs sites favoris. Un utilisateur peut enregistrer plusieurs liens, et plusieurs utilisateurs peuvent enregistrer le même lien selon le cas de chacun de nous. Nous avons par conséquent besoin de deux tableaux, membre_utilisateurs et membre_url_signets, la figure 2 nous montre le schéma de la base de données.

Le tableau membre_utilisateurs contient les noms des utilisateurs (qui correspondent à la clé primaire), les mots de passe, les adresses E-Mail, Avatar et la signature date sans oublier l'id.

Le tableau membre_url_signets contient des paires (Nom_Utilisateur, lien). Le lien est désigné par Signets_URL. Dans ce tableau, le nom d'utilisateur fait référence à un nom d'utilisateur que l'on peut trouver dans le tableau membre_utilisateurs.

Les Listings 1 et 2 contiennent le code SQL permettant de créer cette base de données ainsi qu'un utilisateur pouvant se connecter à cette base de données à partir du Web. Vous pouvez le modifier si vous avez l'intention de l'utiliser sur votre système, en changeant notamment le mot de passe de l'utilisateur !

Listing 1. - Bookmarks.sql - Le fichier SQL permettant de configurer la base de données :

Nous pouvons installer cette base de données sur notre système, en exécutant ces commandes sous le nom de l'utilisateur "root" de MySQL. Vous pouvez le faire avec la commande de votre moniteur SQL à l'aide d'un Onglet intitulé "Importer" puis "choisisser un fichier".

Listing 2. - users.sql - Le fichier SQL permettant de configurer la base de données :

Si on vous demande le mot de passe, vous devrez ensuite saisir "password" en respectant la casse.

Maintenant que la base de données est configurée comme sur la figure 3, nous pouvons attaquer à l'implémentation du site.

Nous terminons ainsi ce premier chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation de base du site et authentification des utilisateurs, etc.


Création de Classes, d'Attributs et d'Opérations en PHP

Programmation orientée objets (1ère partie) :

Polymorphisme :

Un langage de programmation orienté objets doit supporter le polymorphisme, en ce sens que différentes classes doivent pouvoir présenter des comportements différents pour la même opération. Par exemple, supposez que nous ayons défini une classe voiture et une classe bicyclette. Ces deux classes peuvent avoir des opérations déplacement différentes. Dans l'univers des objets réels, cette différentiation pose rarement problème. Il est peu probable, en effet, qu'une bicyclette soit confondue avec une voiture, et démarrée avec une opération déplacement de voiture au lieu d'une opération déplacement de bicyclette. Par contre, un langage de programmation ne possède pas le sens commun du monde réel : il doit par conséquent supporter le polymorphisme pour qu'il soit possible de distinguer l'opération déplacement appropriée à un objet particulier.

Le polymorphisme est plus une caractéristique des comportements que des objets eux-mêmes. En PHP, les fonctions membres d'une classe peuvent être polymorphiques. Les verbes des langages naturels sont un peu l'équivalent dans le monde réel des fonctions membres d'une classe. Considérez la manière dont peut être utilisée une bicyclette dans la vie réelle. Vous pouvez la nettoyer, la déplacer, la démonter, la réparer, ou la peindre, entre autres choses.

Les verbes de la dernière phrase décrivent des actions génériques, parce que le type d'objet auquel ils peuvent être appliqués n'est pas spécifié (ce type d'abstraction concernant les objets et les actions est du reste, une des caractéristiques distinctives de l'intelligence humaine).

Par exemple, le déplacement d'une bicyclette exige des actions complètement différentes de celles qui sont requises pour déplacer une voiture, même si les concepts sont similaires. Le verbe "déplacer" peut être associé à un ensemble particulier d'actions, seulement après que l'objet auquel s'applique le verbe a été défini.

Héritage :

Le concept d'héritage permet de créer une relation hiérarchique entre les classes, au moyen de sous-classes. Une sous-classe hérite des attributs et des opérations de sa super-classe. Par exemple, les voitures et les bicyclettes ont des points commun. Nous pourrions définir une classe véhicule, contenant des attributs tels que la couleur et des opérations telles que le déplacement, qui sont communs à tous les véhicules. Il suffirait ensuite de laisser les classes voiture et bicyclette hériter de la classe véhicule.

Grâce au concept d'héritage, nous pouvons élaborer et enrichir le jeu de classes existantes. A partir d'une simple classe de base, des classes plus complexes et plus spécialisées peuvent être créées, au fur et à mesure des besoins. Cette approche rend le code plus réutilisable, et constitue un des atouts indéniables de la programmation orientée objets.

Création de classes, d'attributs et d'opérations en PHP :

Jusqu'ici, la description que nous avons donnée des classes est plutôt abstraite. Plus concrètement, en PHP, la création d'une classe s'effectue au moyen du mot clé class.

Structure d'une classe :

La définition minimale d'une classe se formule de la manière suivante :

    class nom_de_la_classe

       {

       }

Pour qu'une classe ait une quelconque utilité, elle doit être dotée d'attributs et d'opérations. Pour créer des attributs, il faut déclarer des variables au sein d'une définition de classe, en spécifiant le mot clé var. Le code qui suit crée une classe appelée nom_de_la_classe, dotée des deux attributs $atrribute_1 et $attribute_2 :

    class nom_de_la_classe

       {

          var $attribute_1 ;

          var $attribute_2 ;

       }

La création d'opérations dans une classe s'effectue en déclarant des fonctions au sein de la définition de la classe. Le code qui suit crée une classe dénommée nom_de_la_classe, dotée de deux opérations qui n'effectuent rien de particulier. L'opération operation_1() ne prend aucun paramètre, tandis que operation_2() prend deux paramètres.

    class nom_de_la_classe

       {

          function operation_1()

          {

          }

          function operation_2($parametre_1, $parametre_2)

          {

          }

       }

Constructeurs :

La plupart des classes sont dotées d'un type spécial d'opération appelé "constructeur". Un constructeur est invoqué à la création d'un objet, et normalement il effectue aussi des tâches d'initialisation utiles telles que l'affectation de valeurs de départ aux attributs, ou la création d'autres objets nécessaires à l'objet concerné.

Un constructeur se déclare de la même manière que les autres opérations, si ce n'est qu'il porte le même nom que la classe. Bien qu'un constructeur puisse être invoqué manuellement, son rôle principal est d'être invoqué automatiquement à la création d'un objet. Le code qui suit déclare une classe dotée d'un constructeur :

    class nom_de_la_classe

       {

          function nom_de_la_classe($parametre)

          {

          echo "Constructeur appelé avec paramètre $parametre <BR />" ;

          }

       }

Attention :

Retenez bien que PHP ne supporte pas la surchage (overloading) de fonction, et que vous ne pouvez attribuer le même nom à plusieurs fonctions.

Instanciation :

Une fois que nous avons déclaré une classe, nous devons créer un objet (c'est-à-dire un individu particulier qui appartient à la classe) avec lequel nous pourrons ensuite travailler. Cette étape est aussi qualifiée de "création d'une instance", ou " d'instanciation d'une classe ". Un objet se crée en spécifiant le mot clé new. Il faut par ailleurs spécifier la classe dont l'objet créé sera l'instance, et fournir les paramètres éventuellement requis par le constructeur de la classe.

Le code qui suit déclare une classe dénommée nom_de_la_classe et contenant un constructeur, puis crée quatre objets de type nom_de_la_classe :

    class nom_de_la_classe

       {

          function nom_de_la_classe ($parametre)

          {

          echo "Constructeur appel&eacute; avec param&egrave;tre $parametre <BR />" ;

          }

       }

       $a = new nom_de_la_classe ("Ligne 1") ;

       $b = new nom_de_la_classe ("Ligne 2") ;

       $c = new nom_de_la_classe ("Ligne 3") ;

       $d = new nom_de_la_classe ("") ;

Etant donné que le constructeur est invoqué à chaque création d'objet, ce code produit le résultat suivant :

    Constructeur appelé avec paramètre Ligne 1

    Constructeur appelé avec paramètre Ligne 2

    Constructeur appelé avec paramètre Ligne 3

    Constructeur appelé avec paramètre

Utilisation d'attributs de classe :

Au sein d'une classe, vous pouvez accéder à un pointeur spécial appelé $this. Si un attribut de la classe courante porte le nom $attribute, vous pouvez faire référence à cet attribut par $this->attribute soit pour ajuster, soit pour accéder à la variable à partir d'une opération au sein de la classe.

Le code qui suit illustre l'ajustement et l'accès à un attribut au sein d'une classe :

    class nom_de_la_classe

       {

          var $attribute ;

          function operation($parametre)

          {

          $this->attribute = $parametre ;

          echo $this->attribute ;

          }

       }

Avec certains langages de programmation, il est possible de limiter l'accès aux attributs, en délarant ces données privées ou protégées. PHP n'offre pas cette possibilité, si bien que tous les attributs et toutes les opérations sont visibles hors de la classe qui les contient (en somme, ils sont publics).

Nous pouvons effectuer la même tâche que celle implémentée plus haut, mais cette fois à partir de l'extérieur de la classe. Il suffit simplement pour cela d'utiliser une syntaxe légèrement différente :

    class nom_de_la_classe

       {

          var $attribute ;

       }

       $a = new nom_de_la_classe() ;

       $a->attribute = "Nom_de_Famille" ;

          echo $a->attribute ;

Il est toutefois déconseillé d'accéder directement aux attributs depuis l'extérieur de la classe contenant les attributs. L'un des avantages de l'approche orientée objets réside dans le fait que l'encapsulation est encouragée. Bien que le masquage de données ne puisse être mise en œuvre en PHP, vous pouvez bénéficier des mêmes avantages, à condition toutefois d'avoir un peu de volonté.

Au lieu d'accéder directement aux attributs d'une classe, vous pouvez écrire des "fonctions accesseurs" de sorte à effectuer tous vos accès par le biais d'une seule section de code. Une fonction accesseur peut initialement se formuler de la manière suivante :

    class nom_de_la_classe

       {

          var $attribute ;

          function get_attribute() // renvoie simplement la valeur de $attribute

          {

             return $this->attribute ;

          }

          function set_attribute ($nouvelle_valeur) // donne une nouvelle valeur à $attribute

          {

             $this->attribute = $nouvelle_valeur ;

          }

       }

Ce code ci-dessus fournit simplement des fonctions qui permettent d'accéder à l'attribut d'une variable $attribute. La fonction dénommée get_attribute() renvoie simplement la valeur de la variable $attribute, tandis que la fonction set_attribute affecte une nouvelle valeur à $attribute.

A première vue, ce code peut sembler de peu d'intérêt. Sous sa forme présente, c'est probablement vrai, mais les fonctions accesseur ont une excellente raison d'être : elles permettent d'effectuer tous les accès à un attribut particulier via une seule section de code.

Avec un point d'accès unique, des vérifications peuvent être implémentées pour s'assurer que seules des données sensées sont stockées. S'il apparaît ultérieurement que la valeur de la variable $attribute doit être limitée à la plage comprise entre 0 et 100, nous pourrons ajouter quelques lignes de code, et opérer une vérification avant d'autoriser toute modification. La fonction set_attribute() pourrait être modifiée de la sorte :

          function set_attribute ($nouvelle_valeur) // donne une nouvelle valeur à $attribute

          {

             if ($nouvelle_valeur >= 0 && $nouvelle_valeur <= 100)

             $this->attribute = $nouvelle_valeur ;

          }

Ce changement est trivial. Toutefois, si nous n'avions pas disposé d'une fonction accesseur, nous aurions été dans l'obligation de parcourir chaque ligne de code, et de modifier chaque accès à la variable $attribute. De telles corrections répétitives sont non seulement fastidieuses, mais aussi source d'erreur.

Avec un point d'accès unique, nous sommes libre de modifier l'implémentation sous-jacente. Si pour une raison ou pour une autre nous choisissons de modifier la manière dont est stockée la variable $attribute, l'existence de fonctions accesseur nous permettra d'effectuer facilement nos modifications, en ne changeant le code qu'en un seul emplacement.

Au lieu de stocker $attribute sous forme d'une variable, nous pourrions décider d'extraire $attribute d'une base de données lorsque c'est nécessaire, ou bien de calculer une valeur actualisée en cas de besoin, ou bien de déduire la valeur à partir des valeurs d'autres attributs, ou bien encore d'encoder nos données avec un type de données plus petit. Quels que soient les changements à apporter, il suffira de modifier nos fonctions accesseur. Les autres sections du code ne s'en trouveront pas affectées, du moins tant que les fonctions accesseur accepteront ou renverront les données attendues par les autres parties du programme.

Appel d'opérations de classe :

L'appel d'une opération de classe s'implémente de la même manière que celui d'un attribut de classe. Si nous déclarons la classe suivante :

    class nom_de_la_classe

       {

          function operation_1()

          {

          echo "Bonjour" ;

          }

          function operation_2 ($parametre_1, $parametre_2)

          {

          echo "Blablabla" ;

          }

       }

Et que nous créons un objet de type nom_de_la_classe par exemple, comme suit :

       $a = new nom_de_la_classe() ;

Alors nous pouvons appeler des opérations à la manière des autres fonctions : en spécifiant leur nom, suivi des paramètres requis, placés entre parenthèses. Parce que ces opérations appartiennent à un objet, au contraire, des fonctions normales, il est toutefois nécessaire de spécifier les objets auxquels elles appartiennent. Le nom de l'objet se spécifie comme dans le cas des attributs d'un objet :

       $a->operation_1() ;

       $a->operation_2(25, "test") ;

Si les opérations renvoient des valeurs, les données renvoyées peuvent être récupérées de la manière suivante :

       $z = $a->operation_1() ;

       $y = $a->operation_2(25, "test") ;

Implémentation de l'héritage en PHP :

Une classe peut être déclarée comme étant une sous-classe d'une autre classe, en spécifiant le mot clé extends. Le code qui suit crée une classe dénommée C qui hérite d'une classe précédemment définie et portant le nom D :

    class C extends D

       {

          var $attribute_2 ;

          function operation_2()

          {

          }

       }

En admettant que la classe D ait été déclarée comme suit :

    class D

       {

          var $attribute_1 ;

          function operation_1()

          {

          }

       }

Tous les accès aux opérations et attributs d'un des objets listés ci-dessous seraient valides :

       $b = new C() ;

       $b->operation_1() ;

       $b->attribute_1 = 40 ;

       $b->operation_2() ;

       $b->attribute_2 = 40 ;

Notez que, parce que la classe C hérite de la classe D, nous pouvons faire référence à operation_1() et $attribute_1 bien que ceux-ci soient déclarés dans la classe D. En tant que sous-classe de D, la classe C possède la fonctionnalité et les données de la classe D. En sus, C contient un attribut et une opération qui lui sont propres.

L'héritage ne fonctionne qu'à sens unique. La sous-classe (l'enfant) hérite de sa super-classe (son parent), mais le parent n'hérite pas de son enfant. Il s'ensuit que les deux dernières lignes du code ci-dessous sont incorrectes :

       $a = new D() ;

       $a->operation_1() ;

       $a->attribute_1 = 40 ;

       $a->operation_2() ;

       $a->attribute_2 = 40 ;

En effet, la classe D ne possède pas d'opération de la fonction operation_2(), ni d'attribut attribute_2.

Redéfinition de classe (Overriding) :

Nous venons de voir le cas d'une sous-classe dans laquelle sont déclarés de nouveaux attributs et opérations. Il est également permis de redéclarer les mêmes attributs et opérations. Une telle redéclaration, qualifiée de "redéfinition" (overriding), est utile lorsqu'il est nécessaire de donner à un attribut d'une sous-classe une valeur par défaut différente de celle du même attribut dans la super-classe, ou bien encore pour donner à une opération d'une sous classe une fonctionnalité différente de la même opération dans la super-classe.

Par exemple, si nous disposons de la classe D suivante :

    class D

       {

          var $attribute = "valeur par d&eacute;faut" ;

          function operation()

          {

          echo " Quelque chose de bien <BR /> " ;

          echo " La valeur de \$attribute est la $this->attribute <BR /> " ;

          }

       }

Et qu'il nous apparaisse nécessaire de modifier la valeur par défaut de la variable $attribute, et de fournir une nouvelle fonctionnalité de la fonction operation(), nous pourrions créer la classe C, en redéfinissant $attribute et operation() comme suit :

    class C extends D

       {

          var $attribute = "valeur differente" ;

          function operation()

          {

          echo " Quelque chose de bien, sinon, je ne suis pas content ! <BR /> " ;

          echo " La valeur de \$attribute est la $this->attribute <BR /> " ;

          }

       }

Déclarer C n'affecte en rien la définition originale de D. Considérez les deux lignes de code suivantes :

       $a = new D() ;

       $a->operation() ;

Elles créent un objet de type D, et invoquent sa fonction operation(). Le résultat obtenu à l'exécution de ces deux lignes de code ci-dessus est le suivant :

       Quelque chose de bien

       La valeur de $attribute est la valeur par défaut

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Ce résultat montre bien que la création de C n'a pas affecté D. Si nous créons un objet de type C, nous obtiendrons un résultat différent.

Les lignes suivantes :

       $b = new C() ;

       $b->operation() ;

conduisent à :

       Quelque chose de bien, sinon, je ne suis pas content !

       La valeur de $attribute est la valeur différente

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

De la même manière que de fournir de nouveaux attributs ou opérations dans une sous-classe n'affecte pas la super-classe, la redéfinition d'attributs ou d'opérations dans une sous-classe n'affecte pas la super-classe.

Une sous-classe hérite de tous les attributs et opérations de sa super-classe, à moins de n'opérer des redéfinitions. Lorsqu'une définition de remplacement est fournie, elle devient prépondérante et remplace la définition d'origine.

Contrairement à d'autres langages OO, PHP ne permet pas de redéfinir une fonction tout en gardant la possibilité d'invoquer la version définie dans le parent.

L'héritage peut être implémenté sur plusieurs niveaux. Par exemple, nous pourrions déclarer une classe dénommée E, qui hérite de C, c'est-à-dire qui hérite à la fois des propriétés de C et de celles du parent de C c'est-à-dire de D. Tout comme pour la classe C, nous serions libres de redéfinir et de remplacer dans la classe E des attributs et opérations des parents.

Nous allons voir maintenant la conception de classes afin de bien comprendre cette leçon.

Conception de classes :

Maintenant que nous avons passé en revue les principaux concepts de l'approche orientée objets, concernant les objets et les classes, et la syntaxe de leur implémentation en PHP, nous pouvons examiner comment concevoir des classes qui soient utiles.

Souvent, les classes implémentées dans le code représentent des classes ou des catégories du monde des objets réels. Dans le cadre d'un développement pour le Web, les classes peuvent notamment être utilisées pour représenter des pages Web, des composants d'interface utilisateur, des cartes d'achat, des gestionnaires d'erreur, des catégories de produits, ou des clients.

Les objets peuvent également représenter des instances spécifiques des classes listées plus haut, comme une page d'accueil, un bouton particulier, ou la carte d'achat délivrée à Jean-Pierre à un moment donné. Jean-Pierre lui-même pourrait d'ailleurs être représenté par un objet de type client. Chaque article acheté par Jean-Pierre peut être représenté sous la forme d'un objet, appartenant à une catégorie ou à une classe.

Dans la leçon précédente, en cliquant ici, nous nous sommes servi de fichiers "include" pour donner une apparence cohérente à toutes les pages du site de l'entreprise fictive C.E.I Consultant Électronique-Informatique. Une version plus élaborée encore de ce site peut être obtenue, en utilisant des classes, et en exploitant le concept puissant d'héritage.

Nous voulons être capable d'ajouter rapidement de nouvelles pages Web au site C.E.I, qui aient la même présentation et un comportement similaire. Nous voulons toutefois être en mesure de modifier ces pages, pour les adapter aux différentes partie du site.

Nous allons créer une classe dénommée Page.inc Cette classe aura essentiellement pour rôle de limiter la quantité de code HTML nécessaire à la création d'une nouvelle page. Elle devra nous permettre de modifier les sections qui changent d'une page à l'autre, tout en générant automatiquement les éléments qui se retrouvent dans toutes les pages.

La classe Page devra fournir un cadre flexible pour la création de nouvelles pages, sans compromettre notre liberté.

Etant donné que les pages vont être générées à partir d'un script, et non pas avec du code HTML statique, nous pouvons implémenter diverses possibilités astucieuses, y compris la fonctionnalité suivante :

  • N'autorisez la modification d'éléments de la page qu'en un emplacement seulement. Par exemple, s'il apparaît nécessaire de changer la déclaration de copyright, ou d'ajouter un bouton supplémentaire, nous ne devrions avoir à apporter la modification qu'en un seul point du code.

  • Disposez d'un contenu par défaut pour la plupart des sections de la page, tout en gardant la possibilité de modifier chaque élément si nécessaire, en ajustant des valeurs personnalisées pour des éléments tels que le titre et les méta-balises

  • Identifier la page en cours d'affichage dans le navigateur, et modifier en conséquence les éléments de navigation (par exemple, un bouton permettant de retourner à la page de démarrage n'a pas lieu d'être sur la page de démarrage).

  • Autoriser le remplacement d'éléments standard dans des pages particulières. Par exemple, pour implémenter différents jeux de boutons dans différentes parties du site, nous devons être en mesure de remplacer les boutons standard.

Nous terminons ainsi ce premier chapitre et nous verrons dans le prochain, l'usage de l'implémentation d'une classe.


Génération d'Images

Génération d'images via PHP (1ère partie) :

Une des particularités très utiles de PHP est de permettre la création d'images "à la volée". PHP offre des fonctions prédéfinies de création et de manipulation d'image. Vous pouvez également utiliser la bibliothèque de fonctions spécialisées GD pour créer de nouvelles images ou manipuler des images existantes. Cette leçon explique comment tirer parti des fonctions PHP de génération d'images pour obtenir des effets intéressants et utiles.

Nous illustrerons nos propos par deux exemples : un script de génération à la volée de boutons de sites Web, ainsi qu'un script de génération d'un graphe à barres à partir de données numériques stockées dans une base de données MySQL.

Création d'images :

Les quatre étapes fondamentales de la création d'une image via un script PHP sont les suivantes :

  1. Création d'une image-canevas sur laquelle qu'on peut travailler.

  2. Dessin de formes ou impression de texte sur un canevas.

  3. Génération de l'image finale.

  4. "Nettoyage" des ressources.

Nous allons commencer notre étude en considérant un script simple de création d'une image. Ce script est donné au Linsting 1.

Listing 1. - Image_Simple_Canevas.php - Génération d'une image contenant une ligne et le mot Image Graphique :

Le résultat de l'exécution de ce script est montré à la figure 1.

Nous attirons votre attention que cette image est délicate à être affichée sur certains navigateurs, le code PHP doit être en première ligne (<?PHP), afin que le script puisse fonctionner et évitez de mettre les balises HTML avec le code PHP dans ce cas précis.

Pour visualier l'aperçu, en cliquant ici. [Exemple 1]

Nous allons examiner, en détail chacune des étapes de la création de cette image.

Image-canevas :

Pour commencer l'élaboration ou la modification d'une image via un script PHP, il est nécessaire de créer un identificateur d'image. Pour cela, deux possibilités sont envisageables. La première est de créer un canevas blanc, au moyen de la fonction ImageCreate(), comme dans le script du Listing 1 :

    $Image = ImageCreate($Largeur, $Hauteur) ;

La fonction ImageCreate() prend deux paramètres : le premier est la largeur de la nouvelle image, tandis que le second est sa hauteur. Elle renvoie un identificateur pour la nouvelle image (un identificateur d'image s'apparente beaucoup à une poignée sur un fichier).

La seconde possibilité de création d'image consiste à lire dans un fichier graphique existant, pour ensuite effectuer des opérations telles qu'un filtrage, un redimensionnement, ou des ajouts. Pour cela, vous pouvez utiliser l'une des fonctions ImageCreateFromPng(), ImageCreateFromJpeg() ou ImageCreateFromGif(), selon le format de l'image à lire. Chacune de ces fonctions prend le nom du fichier à lire comme argument, par exemple :

    $Image = ImageCreateFromPng("baseImage.png") ;

Nous verrons plus loin un exemple de mise en œuvre de ces fonctions lorsque nous utiliserons des images existantes pour créer des boutons à la volée.

Dessin ou impression de texte dans une image :

Le dessin ou l'impression de texte dans une image s'effectue réellement en deux étapes.

Tout d'abord, vous devez sélectionner les couleurs avec lesquelles vous voulez dessiner. Comme vous le savez probablement déjà, les couleurs affichées sur l'écran d'un ordinateur sont constitées de quantités bien définies de rouge, de vert et de bleu. Les formats graphiques reposent sur l'utilisation d'une palette des couleurs qui se compose d'un sous-ensemble spécifique de l'ensemble de toutes les combinaisons possibles des trois couleurs rouge, vert et bleu. Pour pouvoir utiliser une couleur particulière dans une image, cette couleur doit figurer dans la palette de l'image.

Pour sélectionner les couleurs d'une image, il faut appeler la fonction ImageColorAllocate(). Celle-ci prend comme paramètres l'identificateur de l'image à traiter, puis les montants de rouge (R), de vert (G) et de bleu (B) de la couleur à sélectionner.

Dans le Listing 1, deux couleurs sont utilisées : le noir et le blanc. Les appels correspondants de la fonction ImageColorAllocate() doivent être formulés de la manière suivante :

    $Blanc = ImageColorAllocate($Image, 255, 255, 255) ; // Couleur du trait diagonal "RGB"

    $Couleur = ImageColorAllocate($Image, 0, 0, 0) ; // Couleur de fond "RGB"

La fonction ImageColorAllocate() renvoie un identificateur de la couleur $Image, qui peut être ensuite utilisé pour accéder à la couleur.

Pour la deuxième étape de dessin d'une image, différentes fonctions sont utilisables selon le motif à dessiner (des lignes, des arcs, des polygones ou du texte).

Les fonctions de dessin offertes par PHP requièrent généralement les paramètres suivants :

  • L'identificateur de l'image ;

  • Le début, et parfois la fin, des coordonnées du motif à dessiner ;

  • La couleur avec laquelle dessiner ;

  • Pour du texte, des informations sur les polices de caractères.

L'exemple considéré ici (voir le Listing 1), fait appel à trois des fonctions de PHP de dessin. Examinons chacune de ces fonctions.

Tout d'abord, le code peint un fond noir, au moyen de la fonction ImageFill() :

    ImageFill($Image, 0, 0, $Couleur) ; // X et Y = 0

La fonction ImageFill() prend respectivement comme argument l'identificateur de l'image ($Image), les coordonnées de départ de la zone à peindre (x et y), ainsi que la couleur de remplissage ($Couleur).

Pour information : les coordonnées de l'image sont spécifiées par rapport au coin supérieur gauche, défini par x = 0, y = 0. Le coin inférieur droit de l'image est défini par les coordonnées x = $Largeur, y = $Hauteur. Les conventions utilisées ici sont donc l'inverse des conventions graphiques habituelles !

Le code trace ensuite un trait qui part du coin supérieur gauche (0,0) jusqu'au coin inférieur droit de l'image ($Largeur, $Hauteur) :

    ImageLine($Image, 0, 0, $Largeur, $Hauteur, $Blanc) ; // Tracé d'une ligne diagonale

La fonction ImageLine() prend comme paramètres l'identificateur de l'image ($Image), le point de départ (x = 0 et y = 0) du trait, le point final ($Largeur, $Hauteur), puis la couleur ($Blanc).

Pour finir, le code ajoute une légende au graphe :

    ImageString($Image, 4, 50, 220, "Image Graphique", $Blanc) ; // Déplacement du texte Image

La fonction ImageString() prend des arguments légèrement différents de ceux des fonctions précédentes. Le prototype de cette fonction est le suivant :

    int ImageString (int $Image, int police, int x, int y, String Image Graphique, int Color)

Cette fonction prend comme paramètres l'identificateur de l'image ($Image), la police (4) les coordonnées (x = 50 et y = 220) du point final d'écriture du texte, le texte à écrire (Image Graphique), la couleur ($Blanc).

La police est spécifiée sous la forme d'un chiffre compris entre 1 et 5. Ces chiffres désignent des polices prédéfinies dans PHP. Vous pouvez également avoir recours à des polices TrueType ou PostScript, via les bibliothèques correspondantes. A chacun de ces jeux de police est associé un jeu de fonctions PHP correspondant. Dans le prochain exemple, nous utiliserons des fonctions TrueType.

L'usage des jeux de fonctions précédemment mentionnés serait dans ce cas judicieux, pour contrer l'effet de crénelage du texte : en effet, les fonctions telles que ImageString() et ImageChar() produisent un texte "aliasé" (crénelé), tandis que les fonctions TrueType et PostScript produisent un texte anti-aliasé (lissé).

La figure ci-après, montre la différence entre la lettre A avec et sans anti-aliasing (lissage). Le texte non lissé présente des effets de crêtes dans les lettres, contrairement au texte lissé. Lorsqu'une image est soumise à un lissage, les pixels en couleurs entre le fond et le texte sont utilisés pour lisser l'apparence du texte et faire disparaître l'effet de "marches d'escalier".

La lettre (A) apparaît crénelée à gauche de la figure, notamment avec les caractères de grande taille. L'anti-aliasing (lissage) permet d'adoucir les courbes et les coins des lettres de cette même figure à droite, (A).

Génération de l'image finale :

Une image peut être générée et affichée soit directement dans le navigateur Web, soit dans un fichier.

Dans l'exemple du Listing 1, l'image est générée dans le navigateur. Le processus de génération se déroule en deux étapes. Tout d'abord, le navigateur Web doit être informé qu'une image lui est transmise, au lieu de texte ou de code HTML. Cette notification est implémentée avec la fonction Header(), en spécifiant le type MIME de l'image comme suit :

    header ("Content-type: image/png") ;

Normalement, le type MIME est la première information envoyée par le serveur Web au navigateur lorsque ce dernier sollicite un fichier. Dans le cas d'une page HTML ou PHP (post exécution), la première information envoyée est la suivante :

    Content-type: text/html

Cette expression informe le navigateur de la manière dont les données qui suivent doivent être traitées.

Dans le cas présent, le navigateur doit être notifié qu'une image lui est envoyée, au lieu de la sortie HTML habituelle.

La fonction Header() utilisée à cette fin transmet des chaînes d'en-tête HTML brutes. Elle peut également s'employer pour effectuer des redirections HTTP. Une redirection HTTP informe le navigateur que c'est une autre page qui doit être chargée, au lieu de la page requise. Les redirections HTTP sont typiquement mises en œuvre lorsque des pages Web sont déplacées. Par exemple :

    Header ("Location: http://www.electronique-et-informatique.fr/Nouvelle_Page_Accueil.html") ;

Concernant la fonction Header(), il est important de noter que cette fonction ne peut être exécutée si un en-tête HTTP a déjà été envoyé pour la page concernée. PHP envoie automatiquement un en-tête HTTP dès lors qu'une sortie est effectuée sur le navigateur. Par conséquent, si une balise PHP d'ouverture est précédée d'une instruction echo, voire d'espace blanc, les en-têtes sont envoyés, et PHP génère un message d'avertissement à l'appel de la fonction Header(). Toutefois, vous pouvez envoyer plusieurs en-têtes HTTP par de multiples appels de la fonction Header() implémentés dans le même script, à condition qu'ils apparaissent tous avant la sortie envoyée vers le navigateur Web.

Une fois que les données d'en-tête ont été envoyées, les données de l'image peuvent être transmises au navigateur via un appel de la fonction ImagePng() :

    ImagePng($Image) ;

Cette ligne de code envoie les données vers le navigateur au format PNG (Portable Network Graphics). Un autre format graphique aurait également pu être utilisé, en appelant la fonction ImageJpeg() (si le support JPEG est activé), JPEG signifie "Joint Photographic Experts Group", ou la fonction ImageGif() (avec une ancienne version de la bibliothèque gd), GIF signifie, "Graphics Interchange Format". Dans ce cas toutefois, il faut d'abord transmettre l'en-tête appropriée, c'est-à-dire :

    header ("Content-type: image/jpeg") ;

ou :

    header ("Content-type: image/gif") ;

La deuxième option envisageable pour générer l'image finale consiste à écrire l'image dans un fichier, et non pas dans le navigateur Web. Pour cela, il suffit de spécifier le nom du fichier comme second argument de la fonction ImagePNG() (ou d'une fonction similaire correspondant à un autre format graphique) :

    ImagePNG ($Image, $Nom_du_Fichier) ;

Dans ce cas, toutes les règles habituelles relatives à l'écriture dans des fichiers via PHP s'appliquent (par exemple, la nécessité d'ajuster correctement les permissions).

Nettoyage final :

Une fois que vous en avez terminé avec une image, il est nécessaire de renvoyer au serveur les ressources qui ont été utilisées, en supprimant l'identificateur de l'image. Ce nettoyage s'implémente au moyen de la fonction ImageDestroy(), comme suit :

    ImageDestroy($Image) ;

Utilisation d'images générées automatiquement dans d'autres pages :

Étant donné qu'un en-tête ne peut être envoyé qu'une seule fois, et qu'un en-tête constitue le seul moyen d'informer le navigateur que des données graphiques lui sont transmises, il est assez délicat d'incorporer dans une page normale des images créées à la volée. Pour ce faire, trois approches sont envisageables :

  1. Toute une page peut être consacrée à l'affichage de l'image (voir le Listing 1).

  2. L'image peut être écrite dans un fichier, comme nous l'avons précédemment mentionné. Une balise <IMG> normale permet ensuite d'y faire référence.

  3. Nous pouvons placer le script de génération de l'image dans une balise IMG.

Nous avons déjà traité les deux premières approches. Penchons-nous à présent d'un peu plus près sur la troisième approche.

Avec la troisième méthode, l'image est incluse en ligne dans du code HTML, avec une balise telle que :

    <img src = "Image_Simple_Canevas.php" alt = "Image_Simple_Canevas.php">

Listing 2. - Image_Simple_Canevas.html - Génération d'une image Graphique, en ligne avec du code HTML :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Au lieu de placer directement une image PNG, JPEG ou GIF dans cette balise, nous spécifions dans la balise IMG le script PHP qui génère l'image. La figure 2 montre un exemple d'application de cette méthode.

Nous terminons ainsi ce premier chapitre de cette leçon, et nous verrons dans le prochain, l'utilisation de Représentation graphique de données numériques.


Téléchargement de fichiers vers le serveur avec PHP

Interaction avec le système de fichiers et le serveur (1ère partie) :

Téléchargement de fichiers vers le serveur avec PHP :

Dans la deuxième leçon, en cliquant ici, "Stockage et récupération des commandes de chez Jean-Pierre", nous avons examiné la manière de lire et d'écrire des données dans des fichiers stockés sur le serveur Web. Dans cette leçon, nous étudierons d'autres fonctions PHP permettant d'interagir avec le système de fichiers du serveur Web.

Nous illustrerons l'étude de ces fonctions par des exemples. Considérons la situation où un site doit être implémenté de sorte que ses visiteurs puissent mettre à jour son contenu (par exemple pour actualiser les informations concernant leur entreprise, ou pour disposer par vous-même d'une interface plus conviviale que FTP) : FTP signifie Fichier Transfert Protocole. Pour une telle implémentation, nous pouvons adopter l'approche consistant à laisser le client télécharger les fichiers vers le serveur sous forme de plein texte ou images selon vos besoins. Le contenu de ces fichiers pourra ensuite être consulté via un modèle conçu et élaboré en PHP, à la manière du modèle de page Web décrit à la sixième leçon, en cliquant ici, "Programmation orientée objets" (1ère et 2ème partie).

Avant de nous lancer dans l'étude des fonctions de manipulation du système de fichiers, nous allons brièvement nous arrêter sur le processus de téléchargement de fichier vers un serveur.

Introduction au téléchargement de fichiers vers un serveur :

Le support du téléchargement HTTP vers un serveur est une fonctionnalité de PHP très utile. Dans ce processus de téléchargement, les fichiers sont transmis du navigateur au serveur via HTTP, c'est-à-dire dans le sens opposé d'un téléchargement de fichier classique. Le téléchargement vers un serveur est généralement implémenté avec une interface de formulaire HTML. Dans l'exemple considéré ici, nous utiliserons l'interface montrée à la figure 1.

Comme vous pouvez le constater sur la figure 1, le formulaire comprend une zone d'envoi dans laquelle l'utilisateur peut chosir le nom du fichier à télécharger vers le serveur, ainsi qu'un bouton Browse (Parcourir) permettant de parcourir les fichiers disponibles localement. Vous découvrez peut-être ce type de formulaire de téléchargement. Nous verrons d'ici peu comment l'implémenter.

Une fois qu'il a choisi un nom du fichier dans la fenêtre d'envoi du fichier, l'utilisateur peut cliquer sur le bouton Send File (Envoi du fichier) pour lancer le téléchargement du fichier vers le serveur, où l'attend un script PHP.

Codage HTML pour un téléchargement de fichier vers un serveur :

L'implémentation d'un téléchargement de fichier vers un serveur implique une syntaxe HTML spécialement conçue à cette fin. Le code HTML du formulaire montré à la figure 1 est donné dans le Listing 1.

Listing 1. - Upload.html - Formulaire HTML pour le téléchargement de fichiers vers un serveur :

Notez que c'est la méthode POST qui est employée dans ce formulaire. Par contre, la méthode GET ne convient pas à l'implémentation de ce processus.

Ce formulaire présente les particularités suivantes :

Dans la balise <FORM>, l'attribut ENCTYPE = "MULTIPART/FORM-DATA" doit être ajusté de la sorte pour que le serveur soit prévenu qu'un fichier lui est envoyé en sus des informations normales relatives au formulaire.

Un champ de formulaire doit être utilisé pour définir la taille maximale de fichier qui peut être téléchargée. Ce champ est caché et est défini de la manière suivante :

    <INPUT TYPE = "HIDDEN" NAME = "MAX_FILE_SIZE" VALUE = "307200">

Ce champ de formulaire doit impérativement porter le nom MAX_FILE_SIZE. L'attribut VALUE fixe une limite à la taille (en octets) des fichiers que les Internautes seront autorisés à télécharger vers le serveur. La valeur est fixée à 307 200 octets ce qui correspond à 300 Ko.

Un INPUT de TYPE FILE doit être spécifié comme suit :

    <INPUT TYPE = "FILE" NAME = "fichier">

Vous êtes libre de choisir la valeur de l'attribut NAME (le nom du fichier) qui vous convient. Gardez toutefois à l'esprit que vous devez mémoriser cette valeur, puisque vous l'utiliserez ultérieurement pour accéder au fichier à partir du script PHP de réception.

Écriture du code PHP pour le traitement d'un fichier téléchargé :

L'écriture du code PHP permettant de récupérer et de traiter le fichier télécharger par l'utilisateur est assez facile.

Lorsqu'un fichier est téléchargé vers un serveur, il est stocké dans un emplacement temporaire du serveur Web, et plus précisément dans le dossier temporaire par défaut du serveur. Si vous ne déplacez pas ou ne renommez pas le fichier avant la fin de l'exécution de votre script, le fichier sera supprimé de cet emplacement temporaire.

En partant du principe que le formulaire HTML comprend un champ appelé fichier, quatre variables sont finalement passées à l'interpréteur PHP :

La valeur contenue dans $_FILES ['fichier'] ['tmp_name'] indique l'emplacement temporaire de stockage du fichier sur le serveur Web.

La valeur contenue dans $_FILES ['fichier'] ['name'] est le nom du fichier dans le système de l'utilisateur.

La valeur contenue dans $_FILES ['fichier'] ['size'] est la taille du fichier en octets.

La valeur contenue dans $_FILES ['fichier'] ['type'] est le type MIME du fichier, par exemple TEXT/PLAIN ou image/gif, ou image/jpg ou image/jpeg et ainsi de suite.

Vous pouvez accéder à ces variables par le biais du tableau $HTTP_POST_FILES, mais ce dernier est obsolète et nous allons plutôt nous servir de la variable $_FILES de la manière suivante :

Notez : Ceci est une 'superglobale', ou variable globale automatique. Cela signifie simplement que cette variable est disponible dans tous les contextes du script. Il n'est pas nécessaire de faire ou de notifier global $variable pour y accéder soit dans les fonctions ou soit dans les méthodes.

Introduction de $_FILES, rendant obsolète $HTTP_POST_FILES.

    $_FILES['fichier']['tmp_name'] ;

    $_FILES['fichier']['name'] ;

    $_FILES['fichier']['size'] ;

    $_FILES['fichier']['type'] ;

Puisque nous connaissons l'emplacement de stockage et le nom du fichier, nous pouvons le copier, en un emplacement plus utile. A la fin de l'exécution du script, le fichier temporaire sera supprimé. Par conséquent, pour conserver le fichier, il est impératif de le déplacer ou de le renommer.

Dans l'exemple considéré ici, les fichiers téléchargés seront utilisés comme articles récents dans un forum de discussion. Par conséquent, nous éliminerons toute balise éventuellement contenue dans les fichiers téléchargés, et nous placerons ceux-ci dans un dossier plus approprié. Le script accomplissant ce traitement est donné au Listing 2.

Listing 2. - Upload.php - Script permettant de récupérer les fichiers envoyés via le formulaire HTML du Listing 1 :

Important : Vous devez créer un répertoire nommé Upload à la racine de votre serveur, sinon, ce script ne peut fonctionner.

Il est intéressant de constater que l'essentiel de ce script consiste en tests d'erreur. Le téléchargement de fichiers vers un serveur présente des risques de sécurité, qui doivent être réduits au minimum. Le fichier téléchargé doit être testé le plus soigneusement possible, de sorte à s'assurer qu'il est sans danger.

Examinons les différentes sections qui composent ce script :

Tout d'abord, le contenu de la variable $Fichier_Temporaire est testé, pour déterminer si le fichier est bien chargé. Sinon, on affiche un message d'erreur ou lorsque la taille du fichier est trop importante, en déterminant dans le formulaire HTML et en insérant le code <INPUT TYPE = "HIDDEN" NAME = "MAX_FILE_SIZE" VALUE = "307200"> qui représente 300 Ko. Bien sûr, vous pouvez modifier la taille du fichier à télécharger, le cas échéant.

Ensuite, ce script détermine si le fichier qui doit être ouvert a réellement été téléchargé, et s'il ne s'agit pas d'un fichier local tel que /etc/livre/password. Nous reviendrons sur ce point un peu plus loin de cette leçon.

Si tous ces tests sont effectués avec succès, le fichier est copié dans le dossier consacré aux fichiers "include". Dans le cas présent, ce dossier est défini par le chemin d'accès Upload/, qui est situé hors de l'arborescence de document Web, et constitue par conséquent une bonne place pour stocher des fichiers à inclure par exemple..

Le fichier est ensuite ouvert, nettoyé de ses éventuelles balises HTML ou PHP au moyen de la fonction (preg_match('#[\x00-\x1F\x7F-\x9F/\\\\]#', $Nom_du_Fichier)).

Pour finir, le contenu du fichier ou plutôt le nom est affiché dans le navigateur de l'utilisateur, pour que celui-ci soit informé que le téléchargement s'est bien déroulé.

Le résultat de l'exécution de ce script est montré à la figure 2.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Pour nous prémunir contre un piratage, le script donné au Listing 2 utilise la fonction is_uploaded_file() pour vérifier que le fichier en cours de traitement, a bien été téléchargé et n'est pas un fichier local tel que /etc/passwd. Cette fonction doit figurer dans la version 4.0.3 de PHP. C'est pourquoi nous avons utilisé ici le code donné en exemple pour cette fonction de cette leçon.

Si votre script de gestion du téléchargement n'a pas été écrit avec suffisamment de prudence, il risque de se trouver aux prises avec un visiteur malin, qui lui fournira son propre nom de fichier temporaire, et le convaincra de traiter ce fichier comme s'il s'agissait d'un fichier téléchargé. Étant donné que la plupart des scripts de téléchargement vers un serveur affichent en retour à l'utilisateur les données téléchargées, ou les stockent en un emplacement à partir duquel ces données pourront être chargées, cette faille peut permettre à des intrus d'accéder à tous les fichiers lisibles par le serveur. Parmi les fichiers exposés au danger peuvent figurer des fichiers très sensibles tels que /etc/passwd, et du code source PHP contenant des mots de passe vers la base de données.

Dans l'exemple précédent, il était supposé que les utilisateurs avaient subi une authentification en amont. Vous devez éviter de laisser tout un chacun télécharger des fichiers vers votre site.

Si vous autorisez malgré tout des utilisateurs non authentifiés à télécharger des fichiers vers votre serveur, vous avez tout intérêt à vous montrer plutôt paranoïaque concernant le contenu de ces fichiers. Vous devez ainsi absolument empêcher qu'un script puisse être téléchargé et exécuté sur votre serveur. Vous devez donc vous montrer prudent non seulement avec le type et le contenu du fichier, comme dans l'exemple considéré ici, mais également avec le nom du fichier. Il est conseillé de renommer les fichiers téléchargés avec des noms inoffensifs.

Nous verrons à la fin de cette leçon, comment exécuter des programmes sur le serveur à partir d'un script PHP.

Nous terminons ainsi ce premier chapitre de cette leçon et nous verrons dans le prochain, L'utilisation de fonctions de manipulation de dossiers, Création et suppression de dossiers


Tests de Variables

Tests de l'État des variables, Structures Conditionnelles, Blocs de Code, Instructions else, elseif, switch et Boucles while, for, etc. (5ème partie) :

Test et ajustement des types de variables :

La plupart des fonctions de variables s'utilisent pour tester le type des variables.

Les deux fonctions de variables les plus générales sont gettype() et settype(). les prototypes de ces fonctions (c'est-à-dire les arguments attendus et les valeurs renvoyées) sont les suivantes :

string gettype(var) ;

int settype(chaîne var, chaîne type) ;

gettype() s'emploie en lui passant une variable. La fonction détermine alors le type de la variable, et renvoie une chaîne contenant le nom du type (c'est-à-dire integer, double, string, array, ou object), ou bien unknown type s'il ne s'agit pas d'un des types PHP standard.

Pour utiliser settype(), il faut passer à la fonction la variable dont le type doit être modifié, ainsi qu'une chaîne contenant le nom du nouveau type à appliquer à la variable. Voici des instructions illustrant l'usage de ces deux fonctions de variables :

$a = 77 ;

echo gettype($a), "<br>" ;

settype($a, "double") ;

echo gettype($a) . "<br>" ;

Lors du premier appel de la fonction gettype(), la variable $a renvoie le type "integer". Après l'appel de settype(), la variable $a renvoie le type "double".

PHP fournit également des fonctions spécifiques d'un certain type de variable, et de test de type. Chacune de ces fonctions prend une variable comme argument, et renvoie soit true, soit false. Ces fonctions sont les suivantes :

is_array()

is_double(), is_float(), is_real() (la même fonction)

is_long(), is_int(), is_integer() (la même fonction)

is_string()

is_object()

Test de l'état d'une variable :

PHP offre plusieurs fonctions pour le test de l'état d'une variable.

La première de ces fonctions est isset(), dont le prototype est le suivant :

int isset(var) ;

Cette fonction prend un nom de variable comme argument, et renvoie true si la variable existe, et false dans le cas contraire.

Vous pouvez supprimer une variable au moyen de la fonction unset(). La fonction unset() a le prototype suivant :

int unset(var) ;

La fonction unset() supprime la variable qui est passée comme argument et renvoie true.

La dernière de ce jeu de fonctions spéciales est la fonction empty(), qui détermine si une variable existe et contient une valeur non vide et non nulle. La fonction empty() renvoie true ou false selon le résultat obtenu. Son prototype est le suivant :

int empty(var) ;

Examinons un exemple utilisant ces trois fonctions dans notre formulaire de commande de chez Jean-Pierre. Insérez les lignes suivantes à la fin de votre script du formulaire en question :

echo isset($ResisQty) ;

echo isset($Jean_Pierre) ;

echo empty($ResisQty) ;

echo empty($Jean_Pierre) ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 6].

La fonction isset() appliquée à la variable $ResisQty devrait renvoyer la valeur true, quelle que soit la valeur saisie dans le champ de formulaire associé à cette variable. Le résultat renvoyé par la fonction empty() appliquée à cette variable dépend par contre de la valeur saisie (ou non saisie) dans le champ de formulaire.

La variable $Jean_Pierre n'existe pas. Par conséquent, la fonction isset() appliquée à ce nom de variable renvoie la valeur false, tandis que la fonction empty() renvoie la valeur true.

Ces fonctions se révèlent très pratiques pour déterminer si l'utilisateur du formulaire a ou non rempli les champs qui lui sont proposés.

Instructions if :

Nous pouvons implémenter une structure if pour prendre une décision. Pour cela, nous devons spécifier une condition. Si la condition se révèle vraie, le bloc de code qui la suit est exécuté. Dans les instructions if, les conditions doivent être spécifiées entre parenthèses ().

Par exemple, si le formulaire de commande en ligne de chez Jean-Pierre est renvoyé par un client sans aucun article commandé, c'est sans doute que le client a actionné par inadvertance le bouton Submit. Plutôt que le message "Commande traitée", le navigateur pourrait lui renvoyer un message plus approprié, tel que : "Votre commande ne contient aucun article !". L'affichage d'un tel avertissement s'implémente très facilement au moyen d'une instruction if :

if ($TotalQty == 0)

echo "<center> <font face = Arial size = 4 color = #FF0000> <b> Votre commande ne contient aucun article ! </b> </font> </center> <BR/>" ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

La condition utilisée ici est $TotalQty == 0. Rappelez-vous que l'opérateur d'égalité (==) est différent de l'opérateur d'affectation (=).

La condition $TotalQty == 0 est vraie si la variable $TotalQty est égale à zéro. Si $TotalQty est différente de zéro, la condition est fausse. Lorsque la condition est évaluée comme vraie (true), l'instruction echo est exécutée.

Blocs de code :

Dans les structures conditionnelles telles qu'une structure if, il est souvent nécessaire d'exécuter plusieurs instructions. Dans ce cas, vous n'avez pas besoin de placer une nouvelle instruction if avant chaque instruction à exécuter : il suffit de regrouper les instructions en un bloc. Pour déclarer un bloc, encadrez-le par des accolades, comme le montre l'exemple suivant :

if ($TotalQty == 0)

{

echo "<font face = Arial size = 4 color = red> <center>" ;

echo "<b> Votre commande ne contient aucun article ! Veuillez recommencer, en vous remerciant de votre visite ! </b> <BR/>" ;

echo "</center> </font>" ;

}

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

Les trois lignes de code placées ici entre les accolades forment un bloc de code. Lorsque la condition est évaluée comme vraie, tout le bloc (c'est-à-dire, les trois lignes qui le constituent) est exécuté. Lorsque la condition se révèle fausse, le bloc est intégralement ignoré par l'interpréteur PHP.

Remarque : Mise en retrait de lignes de code

Comme nous l'avons déjà mentionné, l'interpréteur PHP ignore la mise en forme du code. Il est par conséquent fortement recommandé de mettre en forme le code par des mises en retrait, pour améliorer la lisibilité des programmes. Des mises en retrait judicieuses permettent de discerner d'un seul coup d'oeil les lignes des structures conditionnelles qui sont exécutées lorsque les conditions sont satisfaites, les instructions qui sont regroupées en bloc, et les instructions qui font partie de boucles ou de fonctions. Dans les exemples précédents, l'instruction qui dépend de l'instruction if, et les instructions qui constituent le bloc sont ainsi indentées.

Instructions else :

Souvent, il n'est pas suffisant de décider qu'une action doit être accomplie : il faut aussi choisir celle qui, dans un ensemble d'actions, doit être exécutée.

Une instruction else permet de spécifier une action alternative à accomplir lorsque la condition spécifiée dans une instruction if se révèle fausse. Dans l'exemple concernant le formulaire de commande de chez Jean-Pierre de son entreprise considéré ici, il est nécessaire d'alerter les clients de chez Jean-Pierre s'ils transmettent une commande vide. Par ailleurs, s'ils soumettent une commande valide, il faut leur renvoyer un récapitulatif de leur commande, et non pas un message d'avertissement.

Pour présenter aux clients, soit une alerte, soit un récapitulatif, nous pouvons introduire une instruction else dans notre code, comme suit :

Il suffit de remplacer le code précédent dans l'exemple 8 par celui-ci :

if ($TotalQty == 0)

{

    echo "<font face = Arial size = 4 color = red> <center>" ;

    echo "<b> Vous n'avez pas command&eacute; aucun article sur la page pr&eacute;c&egrave;dente ! Veuillez recommencer, en vous remerciant de votre visite ! </b> <BR/>" ;

    echo "</center> </font>" ;

}

else

{

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #0000FF> <b><u>R&eacute;capitulatif de votre commande</u> : </b> </font> <BR/> <BR/>" ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $ResisQty . "</font>" ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $CondosQty . "</font>" ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $TransisQty . "</font>" ;

}

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

Nous vous rappelons que ce symbole &nbsp; permet de créer un espacement entre les mots ou caractères.

Vous pouvez ainsi implémenter des processus logiques complexes, en imbriquant des instructions if les unes dans les autres. Dans le code qui suit, au lieu de présenter d'emblée un récapitulatif au client lorsque la condition $TotalQty == 0 est évaluée comme vraie, chaque ligne du récapitulatif n'est affichée que si sa propre condition est vraie.

Vous pouvez également remplacer le code précédent dans l'exemple 9 par celui-ci :

if ($TotalQty == 0)

{

    echo "<font face = Arial size = 4 color = red> <center>" ;

    echo "<b> Vous n'avez pas command&eacute; aucun article sur la page pr&eacute;c&egrave;dente ! Veuillez recommencer, en vous remerciant de votre visite ! </b> <BR/>" ;

    echo "</center> </font>" ;

}

else

{

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #0000FF> <b><u>R&eacute;capitulatif de votre commande</u> : </b> </font> <BR/> <BR/>" ;

if ($ResisQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $ResisQty . "</font>" ;

if ($CondosQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $CondosQty . "</font>" ;

if ($TransisQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $TransisQty . "</font>" ;

}

Pour visualiser l'aperçu, en cliquant ici. [Exemple 10].

Instructions elseif :

Dans bon nombre de situations de prise de décision, plusieurs options doivent être prises en compte. L'instruction elseif permet alors de créer une séquence de plusieurs options. L'instruction elseif est une combinaison d'une instruction else et d'une instruction if. Lorsqu'une séquence de conditions est implémentée, le programme peut tester chaque condition, jusqu'à trouver une condition qui soit vraie.

Par exemple, pour les grosses commandes des transistors, le site de chez Jean-Pierre accorde des remises à ses clients. Le principe de ces remises est le suivant :

Moins de 10 transistors achetés : aucune remise ;

11 à 40 transistors achetés : 5% de remise ;

41 à 70 transistors achetés : 10% de remise ;

71 à 99 transistors achetés : 15% de remise.

Nous pouvons créer du code pour calculer la remise accordée, en utilisant des conditions et des instructions if et elseif, ainsi que l'opérateur AND (&&) pour combiner deux conditions :

     if ($TransisQty >=0 && $TransisQty <= 10)

          $Remise = 0 ;

     elseif ($TransisQty >= 11 && $TransisQty <= 40)

          $Remise = 5 ;

     elseif ($TransisQty >= 41 && $TransisQty <= 70)

          $Remise = 10 ;

     elseif ($TransisQty >= 71 && $TransisQty <= 99)

          $Remise = 15 ;

echo "<BR/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 3> Remise &agrave; &nbsp;" . $Remise . "% sur les transistors </font>" ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 11].

Notez que vous pouvez indifféremment écrire elseif ou else if, (avec ou sans espace) mais préférable d'insérer comme suit : elseif et ceci pour éviter de vous induire en erreur sur les totaux.

Dans une telle cascade d'instructions elseif, seule une instruction (ou un bloc d'instructions) sera exécutée. Ce point n'a pas d'importance dans ce cas précis, parce que les différentes conditions spécifiées s'excluent mutuellement les unes des autres, (une seule est vraie à un moment donné). Par contre, lorsque dans un ensemble de conditions plusieurs conditions peuvent être vraies simultanément, seule est exécutée l'instruction, ou le bloc d'instructions, qui succède à la première condition évaluée comme vraie.

Instructions switch :

Une instruction switch est comparable à une instruction if, si ce n'est qu'elle permet d'implémenter une condition susceptible de prendre deux valeurs différentes. Dans une instruction if, la condition peut être évaluée soit comme vraie, soit comme fausse. Dans une instruction switch, la condition peut prendre différentes valeurs, à condition que toutes ces valeurs soient du même type (integer, string ou double). Une instruction case doit alors être implémentée pour gérer chaque valeur possible de la condition, et optionnellement, une instruction case par défaut, pour gérer tous les cas pour lesquels une instruction case spécifique n'a pas été prévue.

Par exemple, le site de chez Jean-Pierre aimerait connaître la forme de publicité qui se révèle le plus profitable à son entreprise. Dans cet objectif, il souhaite inclure une question de sondage dans son formulaire de commande.

Insérez dans la partie HEAD, le code de la feuille de style du formulaire de bon de commande pour le menu déroulant (pop-liste) comme suit :

     <STYLE TYPE="text/css">

     Select#Couleur

     {

     width : 200px; height: 22px; font-weight: bold;

     background: #000000;

     color: #FFFFFF;

     }

     </STYLE>

Insérez les codes HTML à la suite de la balise de fin </tr> dans votre formulaire de commande, et vous devriez obtenir le résultat à la figure 11 :

     <tr>

     <td valign="middle"> <BR><BR><font face="Arial" size="3" color="#000000">Comment avez-vous trouv&eacute; Jean-Pierre ? &nbsp;&nbsp;</font></td>

     <td valign = "bottom"> <select id="Couleur" name="Trouver">

     <option value = "a">Par un client r&eacute;gulier</option>

     <option value = "b">Par la publicit&eacute; t&eacute;l&eacute;vis&eacute;e</option>

     <option value = "c">Par annuaire t&eacute;l&eacute;phonique</option>

     <option value = "d">Par bouche &agrave; oreille</option>

     </select>

     </td>

     </tr>

     </TABLE>

     </FORM>

  </BODY>

</HTML>

Ce code HTML ajoute une nouvelle variable au formulaire de commande, qui peut prendre les valeurs "a", "b", "c", "d". Le traitement PHP de cette variable pourrait s'effectuer au moyen d'une série d'instructions if et elseif, comme suit :

     if ($Trouver = "a")

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client r&eacute;gulier. (Fonction if) </font>" ;

     elseif ($Trouver = "b")

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par la t&eacute;l&eacute;vision suite d'une annonce. </font>" ;

     elseif ($Trouver = "c")

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par le r&eacute;pertoire t&eacute;l&eacute;phonique. </font>" ;

     elseif ($Trouver = "d")

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par la bouche &agrave; oreille. </font>" ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 12].

Nous pourrions également parvenir au même résultat en implémentant une instruction switch :

     switch($Trouver)

     {

     case "a" :

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client r&eacute;gulier. (Fonction if) </font>" ;

     break ;

     case "b" :

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par la t&eacute;l&eacute;vision suite d'une annonce. </font>" ;

     break ;

     case "c" :

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par le r&eacute;pertoire t&eacute;l&eacute;phonique. </font>" ;

     break ;

     case "d" :

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client vis&eacute; par la bouche &agrave; oreille. </font>" ;

     break ;

     default :

     echo "<font face = Arial size = 3 color = #000000><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nous ne savons pas comment ce client nous a trouv&eacute;. </font>" ;

     break ;

     }

Pour visualiser l'aperçu, en cliquant ici. [Exemple 13].

Il est important de comprendre que l'instruction switch exécute chacune des clauses dans l'ordre. L'instructions witch est exécutée ligne par ligne. Au début, aucun code n'est exécuté. Seulement lorsqu'un case est vérifié, PHP exécute alors les instructions correspondantes. PHP continue d'exécuter les instructions jusqu'à la fin du bloc d'instructions du switch, ou bien dès qu'il trouve l'instruction break. Si vous ne pouvez pas utiliser l'instruction break à la fin de l'instruction case, PHP continuera à exécuter toutes les instructions qui suivent.

Une instruction switch se comporte un peu différemment d'une instruction if ou d'une instruction elseif. Une instruction if n'affecte qu'une seule instruction, à moins qu'un bloc de code n'ait été délibérément créé en utilisant une paire d'accolades. Une instruction switch a le comportement inverse : lorsqu'une instruction case d'une structure switch est activée, l'interpréteur PHP exécute les instructions qui suivent jusqu'à rencontrer une instruction break. En l'absence d'instructions break, une structure switch conduit à l'exécution de tout le code succédant à l'instruction case évaluée comme vraie. Lorsque l'interpréteur PHP atteint une instruction break, il exécute la ligne de code qui suit la structure switch.

Comparaison des différentes structures conditionnelles :

Pour le débutant, le choix entre les différentes structures conditionnelles disponibles peut se révéler ardu.

Le choix de l'une ou l'autre structure conditionnelle est en effet assez délicat, puisque tout processus qui peut être implémenté au moyen d'instructions else, elseif, ou switch peut également l'être au moyen d'une série d'instructions if. Essayez d'adopter la structure conditionnelle qui soit la plus lisible dans le contexte du problème traité. C'est ensuite l'expérience qui vous permettra de trouver les réponses les plus appropriées.

Structures de répétition ou itérations :

Les ordinateurs sont toujours précieux lorsqu'il s'agit d'accomplir des tâches répétitives. Lorsqu'une action doit être entreprise de la même manière plusieurs fois de suite, vous pouvez implémenter une boucle pour répéter l'exécution d'un même fragment de code au sein d'un programme (ou de vos programmes).

Le site de chez Jean-Pierre veut afficher dans chaque commande de ses clients un tableau donnant le coût d'expédition de la commande. Avec la logistique d'expédition adoptée par l'entreprise de Jean-Pierre, le coût d'expédition dépend de la distance parcourue par la commande entre l'entrepôt et le client. Ce coût peut être calculé par une simple formule. Le résultat recherché est montré à la figure 12.

Nous ne mettons pas le listing complet dans cette leçon, puisque le code HTML et répétitif. Pour visualiser le code et faire copier-coller, il suffit d'ouvrir son fichier source à l'aide du bouton droit de la souris.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 14].

Vous pouvez observer que ce code est long est répétitif.

Les structures de répétition permettent d'exécuter une instruction ou un bloc de code de manière répétitive.

Boucles while :

La boucle while est la structure de répétition la plus simple du langage PHP. Tout comme une structure if, elle repose sur le test d'une condition. Une boucle while diffère toutefois d'une instruction if par le fait qu'elle exécute le bloc de code qui la suit tant que la condition reste vraie. Une structure if exécute une fois seulement le bloc de code qui suit lorsque la condition est vraie.

Une boucle while s'utilise, en général lorsque le nombre de répétitions à effectuer n'est pas connu à l'avance. Lorsque le nombre de répétitions est fixe, mieux vaut employer une boucle for.

La structure d'une boucle while est la suivante :

     while (condition) expression ;

La boucle while qui suit produit l'affichage des nombres compris entre 1 et 10 :

     <?php

     $numerique = 1 ;

     while($numerique <= 10)

     {

     echo "<b> <BR> <font face=arial size=3 color=#0000FF>" . $numerique . "<BR>" ;

     $numerique++ ;

     }

     ?>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 15].

Au début de chaque répétition, la condition est testée. Si la condition se révèle fausse, le bloc n'est pas exécuté et l'exécution de la boucle prend fin. L'interpréteur PHP passe alors à l'instruction qui suit la boucle while.

Nous pouvons implémenter une boucle while pour accomplir une tâche un peu plus utile, comme l'affichage du tableau des coûts d'expédition montré à la figure 12.

Le code donné dans le listing ci-dessous utilise une boucle while pour générer le tableau des coûts d'expédition.

<HTML>

<HEAD>

<TITLE> Structures d'it&eacute;rations </TITLE>

</HEAD>

<BODY>

<CENTER> <BR> <BR> <BR>

<table border = 0 cellpadding = 3>

<tr bgcolor="#cccccc">

<td width = "170" align = "center"> <font face = "Arial" size = "3" color = "#000000"> <b>Distance</b> </font> </td>

<td width = "150" align = "center"> <font face = "Arial" size = "3" color = "#000000"> <b>Coût</b> </font> </td>

</tr>

<?php

$Distance = 50 ;

while($Distance <= 250)

{

echo "<tr>\n <td align = center> <font face=Arial size=3 color=#005500> <b>$Distance km</b> </font> </td>\n" ;

echo "<td align = center> <font face=Arial size=3 color=#005500> <b>" . $Distance / 10 . "&nbsp;euros</b> </font> </td>\n </tr>\n" ;

$Distance += 50 ;

}

?>

</table>

</CENTER>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 16].

Boucles for :

L'emploi que nous avons fait de la boucle while dans l'exemple précédent est très classique. Nous avons défini un compteur au début de la boucle. Avant chaque itération, le compteur est testé par une condition. A la fin de chaque itération, le compteur est modifié.

Ce style de boucle peut être implémenté de manière plus compacte, en utilisant une boucle for.

La structure d'une boucle for est la suivante :

    for(expression_1 ; condition ; expression_2) expression_3 ;

expression_1 est exécutée une fois au début de la boucle, et contient normalement la valeur initiale d'un compteur.

L'expression condition est testée avant chaque itération. Si la condition se révèle fausse, l'exécution de la boucle s'interrompt. Cette expression est généralement utilisée pour tester si le compteur a atteint une certaine limite.

expression_2 est exécutée à la fin de chaque itération, et s'emploie généralement pour ajuster la valeur du compteur.

expression_3 est exécutée une fois par itération. Cette expression est généralement un bloc de code, et constitue le corps de la boucle.

L'exemple donné dans l'exemple 16, et qui illustre l'usage d'une boucle while, peut être réécrit avec une boucle for. Le code PHP devient alors :

      <?php

      <for($Distance = 50; $Distance <= 250; $Distance += 50)

   {

      echo "<tr>\n <td align=right> <font face=Arial size=3 color=#005500> <b>$Distance km |</b> </font> </td>\n" ;

      echo "<td align=right> <font face=Arial size=3 color=#005500> <b> " . $Distance / 10 . " euros |</b> </font> </td>\n </tr>\n" ;

   }

      ?>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 17].

Les deux versions proposées ici, avec une boucle while et avec une boucle for, sont identiques d'un point de vue fonctionnel. La boucle for apparaît légèrement plus compacte (elle contient deux lignes de moins que par rapport à la boucle while).

Ces deux types de boucle sont équivalents : aucun n'est réellement meilleur que l'autre. Dans chaque situation, il vous appartient de choisir celui qui vous semble le plus intuitif.

Notez qu'il est possible de combiner des variables dynamiques avec une boucle for pour traiter automatiquement une série de champs de formulaire répétitifs. Par exemple, dans le cas d'un formulaire contenant des champs dénommés name_1, name_2, name_3, et ainsi de suite. Vous pouvez implémenter leur traitement de la manière suivante :

      for ($i=1; $i <= $numnames; $i++)

      {

      $$temp="name$i" ;

      echo $$temp . "<br>" ; // Ou tout autre traitement nécessaire

      }

Pour visualiser l'aperçu, en cliquant ici. [Exemple 18].

En créant dynamiquement les noms des variables ($$temp), nous pouvons accéder successivement aux différents champs du formulaire.

Boucles do ... while :

Le dernier type de boucle qu'il nous reste à étudier a un comportement légèrement différent. La structure d'une boucle do...while est la suivante :

      do

      expression ;

      while(condition) ;

Une boucle do...while diffère d'une boucle while lorsque sa condition est testée à la fin de chaque itération. Il s'ensuit que dans une boucle do...while, l'instruction ou le bloc formant le corps de la boucle est systématiquement exécuté une fois au moins.

Même dans l'exemple qui suit, où la condition se révèle fausse d'emblée et ne peut jamais être vraie, la boucle est exécutée une fois avant que la condition soit évaluée et que l'exécution de la boucle prenne fin :

      <?php

      $ValeurNumerique = 1000 ;

      do

      {

      echo "<font face=Arial size=5 color=#0000FF>" . $ValeurNumerique . "</font> <BR/>" ;

      }

      while($ValeurNumerique < 1) ;

      ?>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 19].

Interruption de l'exécution d'une structure de contrôle ou d'un script :

Pour interrompre l'exécution d'un morceau de code par exemple, trois approches sont envisageables, selon l'effet recherché.

Pour arrêter l'exécution d'une boucle, vous pouvez utiliser l'instruction break, comme nous l'avons déjà fait dans la section traitant de la structure switch. Lorsqu'une instruction break est insérée dans une boucle, l'exécution du script se poursuit par la ligne du script qui succède à la boucle.

Pour interrompre l'exécution d'une itération d'une boucle, et passer directement à l'itération suivante, vous pouvez employer l'instruction continue.

Pour interrompre définitivement l'exécution d'un script PHP, vous pouvez utiliser l'instruction exit. Celle-ci apparaît particulièrement utile lors de processus de vérification d'erreur. Par exemple, l'exemple 10 donné plus haut de cette leçon, pourrait être modifié de la manière suivante :

if ($TotalQty == 0)

{

    echo "<font face = Arial size = 4 color = red> <center>" ;

    echo "<b> Vous n'avez pas command&eacute; aucun article sur la page pr&eacute;c&egrave;dente ! Veuillez recommencer, en vous remerciant de votre visite ! </b> <BR/>" ;

    echo "</center> </font>" ;

}

else

{

    exit ; // On interrompre une partie du programme pour trouver l'erreur par exemple ...

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #0000FF> <b><u>R&eacute;capitulatif de votre commande</u> : </b> </font> <BR/> <BR/>" ;

if ($ResisQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $ResisQty . "</font>" ;

if ($CondosQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $CondosQty . "</font>" ;

if ($TransisQty >0)

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face = Arial size = 4 color = #000000>" . $TransisQty . "</font>" ;

}

Pour visualiser l'aperçu, en cliquant ici. [Exemple 20].

L'appel de la fonction exit empêche l'interpréteur PHP d'exécuter le reste du script.

Important : ne pas mettre l'instruction exit entre les instructions if et else, car cela ne peut fonctionner ainsi, le programme continuera à fonctionner jusqu'à la fin de sa boucle If - else, en revanche, vous pouvez mettre exit, en sortie de else comme évoqué en couleur rouge.

Fin de cette première leçon , la prochaine sera consacrée "à l'enregistrement de la commande de sorte à pouvoir la retrouver et la traiter ultérieurement", que nous verrons par la suite de la deuxième leçon.


Travailler avec votre base de données MySQL

Travailler avec votre base de données MySQL (1ère partie) :

Dans cette leçon, nous allons présenter le langage de requêtes structurées (SQL, Structured Query Language), et nous verrons comment l'utiliser pour interroger des bases de données. Nous allons continuer le développement de la base de données de chez Jean-Pierre, en apprenant à insérer, à supprimer et à mettre à jour des données, et à poser des questions à la base de données.

Tout d'abord, nous commencerons par présenter SQL, et verrons en quoi cet outil peut nous être utile ? !

Si vous n'avez pas configuré la base de données de chez Jean-Pierre, vous devez le faire avant d'exécuter les requêtes SQL de cette leçon. Vous trouverez tous les détails de cette procédure aux leçons précédentes, en cliquant ici . (1ère à la 3ème partie).

Qu'est-ce que SQL ?

SQL signifie Structured Query Language, ou langage de requêtes structurées. C'est le langage le plus répandu pour accéder à des systèmes de gestion de base de données relationnelles (RDBMS). SQL permet de stocker et de récupérer des données avec ces bases de données. Il est utilisé par des systèmes de base de données comme MySQL, Oracle, PostgreSQL, Sybase, et Microsoft SQL Server, pour ne citer qu'eux.

Il existe un standard AINSI pour SQL, et les systèmes de bases de données comme MySQL implémentent ce standard. Généralement, ces systèmes y ajoutent certaines caractéristiques qui leur sont propres. Le système de privilèges de MySQL en est un bon exemple.

Vous avez peut-être déjà entendu les expressions Data Definition Languages (DDL), pour la définition des bases de données, et Data Manipulation Languages (DML), pour l'interrogation des bases de données. SQL est compatible avec ces deux standards. Dans les leçons précédentes, en cliquant ici, (1ère à la 4ème partie), nous avons vu la définition des données (DDL) dans SQL, donc, nous nous en sommes déjà servi un peu. Vous vous servez d'un DDL lorsque vous configurez pour la première fois une base de données.

La partie DML et SQL est utilisée bien plus souvent, puisqu'elle l'est chaque fois que vous enregistrez des données dans une base de données, ou que vous les lisez.

Insertion de données dans la base de données :

Avant de pouvoir travailler avec une base de données, vous devez y placer des informations. La plupart du temps, vous vous servirez de l'instruction SQL INSERT.

Rappelez-vous que les RDBMS contiennent des tableaux, qui renferment à leur tour des lignes de données, organisées en colonnes. Chaque ligne d'un tableau décrit normalement un objet du mode réel, ou une relation, et les valeurs d'une colonne pour une ligne donnée correspondent aux informations relatives à un objet réel particulier. Nous pouvons nous servir de l'instruction INSERT pour ajouter des lignes de données dans la base de données.

Voici le format classique d'une instruction INSERT :

    INSERT [INTO] table [(column_1, column_2, column_3, ...)] VALUES

    (value_1, value_2, value_3, ...) ;

Par exemple, pour insérer un enregistrement dans le tableau les_clients de chez Jean-Pierre, vous pouvez saisir la commande suivante :

    INSERT INTO les_clients VALUES

    (NULL, "Jean-Jacques DUPOND", "54 rue Alouette", "Le Vésinet") ;

Nous mettons deux captures que vous devriez obtenir ceci :

Vous remarquerez que nous avons remplacé table par le nom du tableau dans lequel nous souhaitions placer nos données, et value par nos valeurs. Toutes les valeurs de cet exemple ont été mises entre guillemets. Dans MySQL, les chaînes de caractères doivent toujours être mises entre simples ou doubles guillemets (dans cette leçon, nous utiliserons ces deux types de guillemets). Les nombres et les dates n'ont pas besoin de guillemets.

L'instruction INSERT mérite quelques commentaires.

Les valeurs spécifiées sont utilisées pour remplir le tableau, dans l'ordre où elles sont fournies. Cependant, si vous souhaitez remplir uniquement certaines colonnes, ou si vous voulez spécifier les valeurs dans un ordre différent, vous pouvez préciser le nom des colonnes dans cette instruction. Par exemple :

    INSERT INTO les_clients (nom, ville) VALUES

    ("Jean-Patrick BEESSE", "Machin-Les-Vallées") ;

Cette approche n'est intéressante que si vous possédez des données partielles pour un enregistrement particulier, ou si certains champs de l'enregistrement sont optionnels. Voici une autre syntaxe similaire :

    INSERT INTO les_clients

    SET nom = "Michael-Pierre ROBERT" ,

    adresse = "75 Avenue de Paris" ,

    ville = "AUDIERNE" ;

Nous mettons une capture afin que vous puissiez vous rendre compte, si vous eûtes enregistré les exemples ci-dessus dans la base de données, (pour vos essais par exemple).

Vous remarquerez également que nous avons spécifié la valeur NULL pour la colonne client_id lorsque nous avons ajouté Jean-Jacques DUPOND, et que nous avons ignoré cette colonne lorsque nous avons ajouté les autres clients. Vous vous rappelez peut-être que lorsque nous avons configuré la base de données, nous avons spécifié client_id comme étant la clé primaire du tableau les_clients, c'est pourquoi cette procédure peut vous sembler étrange. Cependant, nous avons spécifié ce champ avec l'attribut AUTO_INCREMENT. Cela signifie que si nous insérons une ligne avec la valeur NULL (ou aucune valeur) dans ce champ, MySQL génère le prochain numéro dans la séquence d'auto-incrémentation, et insère automatiquement la prochaine valeur. Cette caractéristique est très utile.

Il est également possible d'insérer plusieurs lignes dans un tableau d'un seul coup. Chaque ligne doit être mise entre parenthèses, et les ensembles de parenthèses doivent être séparés par des virgules.

Nous avons réuni quelques données pour remplir la base de données, grâce à quelques instructions INSERT, qui se servent de l'approche multilignes que nous venons de voir. Le script correspondant se trouve dans le TEXTAREA du listing 1 ci-après : ou en cliquant ici

Sur certains serveurs locaux y compris les serveurs à distant (FAI), il se peut que le programme SQL ne peut fonctionner, dans ce cas là, il suffit d'effacer l'attribut use bouks ;

Nous vous rappelons pour charger le fichier SQL dans la base de données MySQL, de revoir la leçon précédente, en cliquant ici. (Voir le paragraphe Création des Tableaux de la base de données avec sa Capture d'écran).

Listing 1. - Jean_Pierre_INSERT.sql - Le programme SQL permettant de remplir les tableaux de chez Jean-Pierre (5 Clients + 3 en exemple ci-dessus).

A noter : Nous allons mettre trois captures pour vous montrer les détails de cette base de données afin de faciliter vos travaux. En revanche, nous ne pouvons mettre toutes les captures, afin d'éviter les encombrements de cette leçon mais, nous en mettrons d'autres lorsque cela sera utile.

Veuillez noter que nous avions omis les ponctuations pour des raisons de fiabilité concernant les serveurs locaux. Tandis que les serveurs à distant ne posent aucun problème si ces derniers fonctionnent correctement selon les fournisseurs (FAI).

Nous terminons ainsi ce premier chapitre (1ère partie de cette leçon) et nous verrons dans le prochain, l'usage pour lire des données dans la base de données et de récupérer des données avec des critères spécifiques ainsi que certaines modifications des tableaux parmi tant d'autres.


Utilisation de fopen, fwrite, fclose

Utilisation de "fopen" pour Ouvrir un Fichier, Écriture (fwrite()), Lecture et Fermeture de ce même Fichier, etc. (1ère partie) :

Maintenant que vous savez accéder aux données saisies dans un formulaire HTML, et que vous savez également comment manipuler ces données, nous pouvons examiner les moyens de stockage de ces informations, qui permettent de les retrouver et de les utiliser ultérieurement. Le plus souvent, y compris dans l'exemple construit dans la première leçon précédente, les données récupérées à partir des formulaires HTML doivent être stockées en vue d'un usage ultérieur. Dans l'exemple considéré jusqu'ici, les commandes passées en ligne par les clients doivent être stockées, de sorte à pouvoir les traiter et les satisfaire ultérieurement.

Dans cette deuxième leçon, nous verrons comment, dans le contexte de l'exemple précédent, écrire dans un fichier la commande transmise par un client, et comment la lire ensuite dans ce fichier. Nous verrons également qu'un tel stockage ne constitue pas toujours une bonne solution. Pour des nombres élevés de commandes, l'emploi d'un système de gestion de base de données, tel que MySQL, est indispensable.

Stockage et récupération des commandes de chez Jean-Pierre :

Deux modes de stockage des données sont réellement envisageables : dans des fichiers "plats", ou dans une base de données.

Un fichier plat (on parle également de fichier "à plat") peut être enregistré sous de nombreux formats. En général toutefois, l'expression "fichier plat" est employée pour désigner un simple fichier texte. Dans notre exemple, nous écrirons les commandes des clients dans un fichier texte, sous la forme d'une commande par ligne.

Ce mode de stockage est très simple à mettre en place, mais se révèle assez limité, comme nous le verrons un peu plus loin dans cette leçon. Dès lors que les informations à traiter sont un tant soit peu nombreuses, l'usage d'une base de données est fortement recommmandé. Les fichiers plats restent néanmoins très utile dans certaines situations, et méritent que vous sachiez les manipuler.

Dans cette leçon, nous considérerons une version légèrement modifiée du formulaire de commande de chez Jean-Pierre examiné dans la première leçon. Nous commencerons avec ce formulaire de commande, et avec le code PHP que nous avons écrit pour traiter les données entrées par les clients. (Voir la première leçon, en cliquant ici) et concernant la leçon complète, cliquez ici .

Le formulaire modifié que nous allons à présent utiliser comprend un champ supplémentaire pour la saisie de l'adresse de livraison du client (voir figure 1).

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Nous vous rappelons que pour visualiser le code source du formulaire de commande de chez Jean-Pierre, il suffit de cliquer sur le bouton droit de votre souris.

Pour ajouter un champ supplémentaire dans le formulaire de commande, il suffit d'insérer le code HTML ci-après :

    <FORM ACTION="ESSAI_ORDRE_COMMANDE.php" METHOD="POST" <!-- Dans cet exemple que le nom de la page soit intitulée : "ESSAI_ORDRE_COMMANDE.php" -->

    <tr>

    <td><BR><BR><font face="Arial" size="3" color="#000000"><b>&nbsp;&nbsp;&nbsp;Adresse :</b></font></td>

    <td align ="center" valign="bottom"> <input type="text" name="Adresse" size="40" MAXLENGTH="90"</td>

    </tr>

    <BR><BR> <input type="Submit" value="Valider la commande">

    </FORM>

Maintenant, pour transmettre ou récupérer les informations du champ de l'adresse du formulaire sur une autre page dans l'intitulé : "ESSAI_ORDRE_COMMANDE.php" par exemple, il suffit d'insérer le code PHP comme ci-après :

    <?php

    echo "<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face=Arial size=4 color=#000000>Adresse :</font> <font face=Arial size=4 color=#005500>" . $Adresse = $_POST ["Adresse"] . "</font>" ;

    ?>

Nous vous répétons que vous pouvez faire plusieurs essais ou modifier le code PHP ou HTML afin que vous puissiez bien comprendre le processus.

Le champ de saisie de l'adresse de livraison est dénommé Adresse. Nous pouvons ainsi accéder aux données de ce champ via la variable $Adresse pour les traiter via des instructions PHP, en supposant que nous ayons adopté le style court pour les variables de formulaire. Rappelez-vous qu'avec le style long, nous utiliserions les syntaxes $HTTP_GET_VARS["Adresse"] ou bien $HTTP_POST_VARS["Adresse"] (pour de plus amples détails à ce sujet, reportez-vous à la première leçon si vous n'avez pas bien compris à cet effet.

Nous écrirons dans un même fichier chaque nouvelle commande transmise par un client. Nous construirons ensuite, une interface Web, grâce à laquelle l'équipe de Jean-Pierre pourra visualiser les commandes reçues.

Tour d'horizon sur les fonctions de traitement de fichier :

L'écriture dans un fichier s'effectue en trois étapes :

  1. Ouverture du fichier. Si le fichier n'existe pas encore, il doit être créé.

  2. Ecriture des données dans le fichier.

  3. Fermeture du fichier.

De la même manière, la lecture des données d'un fichier s'effectue en trois étapes :

  1. Ouverture du fichier. Si l'ouverture du fichier se révèle impossible (par exemple, parce que le fichier n'existe pas), nous devons le détecter et interrompre correctement le processus engagé.

  2. Lecture des données dans le fichier.

  3. Fermeture du fichier

Lors de la lecture de données dans un fichier, vous pouvez spécifier la proportion du fichier à lire en une fois. Nous allons décrire en détail les différentes possibilités qui se présentent à nous.

Pour l'instant, commençons par ouvrir un fichier.

Ouverture d'un fichier :

En PHP, l'ouverture d'un fichier s'effectue au moyen de la fonction fopen(). Lors de l'ouverture d'un fichier, vous devez spécifier le mode de fichier, c'est-à-dire, la manière dont vous voulez utiliser le fichier.

Mode de fichier :

Le système d'exploitation exécuté sur le serveur a besoin de connaître l'usage que l'utilisateur envisage de faire du fichier qui va être ouvert. Plus précisément, il doit savoir si le fichier pourra être ouvert par un autre script une fois que vous l'aurez ouvert, et doit déterminer si vous (le propriétaire du script) bénéficiez de la permission requise pour utiliser le fichier sous ce mode. Les modes de fichier fournissent au système d'exploitation un mécanisme pour déterminer comment gérer les requêtes d'accès émanant d'autres utilisateurs ou d'autres scripts, et une méthode pour vérifier que vous avez la permission d'accès adéquate pour accéder à ce fichier particulier.

Lorsque vous ouvrez un fichier, vous devez vous prononcer sur trois points :

  1. Vous avez la possibilité d'ouvrir un fichier en lecture seule, en écriture seule, ou bien encore en lecture et en écriture.

  2. Pour écrire des données dans le fichier, vous pouvez soit remplacer le contenu existant par vos nouvelles données ("écraser" le contenu"), soit ajouter les nouvelles données à la suite du contenu existant.

  3. Si vous écrivez un fichier dans un système capable de faire la distinction entre des fichiers binaires et des fichiers texte, vous pouvez spécifier le type de fichier voulu.

La fonction fopen() permet de spécifier vos choix concernant ces trois points.

Utilisation de fopen() pour ouvrir un fichier :

Supposons que nous voulions enregistrer une commande client dans le fichier regroupant les commandes de l'entreprise de chez Jean-Pierre. L'ouverture de ce fichier peut s'implémenter de la manière suivante :

    $fp = fopen("$DOCUMENT_ROOT/../Orders/Commandes.txt", "w");

Lorsqu'elle est invoquée, la fonction fopen attend deux ou trois paramètres. Le plus souvent, vous ne spécifierez que deux paramètres comme dans la ligne de code ci-dessus.

Mais attention au chemin d'accès, le premier paramètre à spécifier est le nom du fichier à ouvrir, avec éventuellement le chemin d'accès correspondant, comme dans l'instruction précédente (le fichier Commandes.txt est stocké dans le dossier Orders). Dans l'exemple montré ici, la variable PHP prédéfinie $DOCUMENT_ROOT est utilisée pour pointer sur la racine de l'arborescence de documents du serveur Web. La paire de points ("..") est interprétée comme le dossier parent du dossier $DOCUMENT_ROOT. Ce dossier est placé hors de l'arborescence de documents, pour des raisons de sécurité. En effet, le fichier doit demeurer inaccessible à partir du Web, si ce n'est par le biais de l'interface que nous allons fournir à cet effet. Un tel chemin d'accès est qualifié de "relatif", parce qu'il décrit un emplacement dans le système de fichier par rapport à $DOCUMENT_ROOT.

Vous pouvez toutefois également spécifier un chemin d'accès absolu, c'est-à-dire à partir du dossier racine (/ dans un système Unix et typiquement C:\ dans un système Windows). Sur notre serveur Unix, ce serait /home/book/orders. Si vous choisissez un chemin d'accès absolu, en particulier si vous faites héberger votre site sur le serveur d'un tiers, il peut arriver que le chemin d'accès se trouve modifié. Les conséquences peuvent alors se révéler douloureuses, par exemple lorsque des administrateurs système modifient la structure des dossiers sans crier gare, et qu'il faut précipitamment changer les chemins absolus dans un grand nombre de scripts.

Lorsque aucun chemin d'accès n'est spécifié, le fichier est créé ou rechercher dans le même dossier que celui contenant le script. Ce processus est toutefois différent lorsque PHP est exécuté par le biais d'un wrapper CGI et dépend de la configuration du serveur.

Dans un environnement Unix, vous devez utiliser des barres obliques (/) dans les chemins d'accès aux dossiers, tandis que sur une plate-forme Windows, vous pouvez aussi bien employer que des barres obliques inversées (\). Si vous utilisez des barres obliques lors d'un appel de la fonction fopen() vous devez les spécifier "avec échappement" (c'est-à-dire, en les balisant comme caractères spéciaux) pour qu'ils soient correctement compris par fopen. pour cela, il suffit de faire précéder la barre oblique d'une barre oblique supplémentaire, comme suit :

    $fp = fopen("..\\..\\Orders\\Commandes.txt", "w") ;

Le deuxième paramètre à passer à la fonction fopen() est le mode de fichier, qui doit être spécifié sous forme de chaîne, et indique la manipulation prévue sur le fichier. Dans l'exemple considéré ici, nous avons donné la valeur "w" à ce deuxième paramètre, qui signifie que le fichier doit être ouvert en vue d'y écrire des données. Le tableau de la figure 2 récapitule les divers modes de fichier disponibles. (Extrait de nos catalogues).

Tableau de la figure 2 : Récapitulatif des différents modes de fichier qui peuvent être spécifiés dans un appel de fopen()
Mode | Signification
r | Mode de lecture seule : le fichier ouvert en lecture, à partir de son début.
r+ | Mode de lecture : le fichier est ouvert en lecture et en écriture, à partir de son début.
w | Mode d'écriture seule : le fichier est ouvert en écriture, à partir de son début. Si le fichier existe déjà, son contenu est écrasé. Dans le cas contraire, le fichier est créé.
w+ | Mode d'écriture : le fichier est ouvert en écriture et en lecture, à partir de son début. Si le fichier existe déjà, son contenu est écrasé. Dans le cas contraire, le fichier est créé.
a | Mode d'écriture seule avec ajout des données à la fin du contenu existant, le cas échéant. Si le fichier n'existe pas encore, il est créé.
a+ | Mode d'écriture / lecture avec ajout des données à la fin du contenu existant, le cas échéant. Si le fichier n'existe pas encore, il est créé.
b | Mode binaire : s'utilise en conjonction avec l'un des autres modes de fichier, dans les systèmes de fichiers capables de faire la distinction entre les fichiers binaires et des fichiers texte (les systèmes Windows ont cette capacité, mais pas les systèmes Unix)

Le choix de mode de fichier approprié dépend de la manière dont le système doit être utilisé. Dans l'exemple donné ici, le choix du mode "w" implique que le fichier ne pourra contenir qu'une seule commande client à la fois : à chaque entrée d'une nouvelle commande, la commande existante sera effacée et remplacée par la nouvelle commande. Ce choix n'est pas le plus judicieux, à l'évidence, et le mode "a" apparaît plus approprié :

    $fp = fopen("../../Orders/Commandes.txt", "a") ;

Le troisième paramètre admis par la fonction fopen() est optionnel. Il s'utilise pour rechercher le include_path d'un fichier (défini dans la configuration EasyPHP). Pour effectuer une telle recherche, ajustez la valeur de ce paramètre sur la valeur 1. Dans ce cas, il n'est pas utile de fournir un nom de dossier ou un chemin d'accès :

    $fp = fopen("Commandes.txt", "a", 1) ;

Lorsque l'ouverture d'un fichier avec la fonction fopen() réussit, celle-ci renvoie un pointeur sur le fichier, qui doit être stocké dans une variable ($fp dans le cas présent). Cette variable permet ensuite d'accéder au fichier pour y lire ou y écrire des données.

Écriture dans un fichier :

En programmation PHP, l'écriture dans un fichier est relativement simple à implémenter. Vous pouvez utiliser l'une ou l'autre des fonctions fwrite() et fputs() ; fputs() est un alias de fwrite(). Dans l'exemple considéré ici, l'appel de fwrite() peut s'effectuer de la manière suivante :

<HTML>

<HEAD>

<TITLE> &Eacute;criture dans un Fichier </TITLE>

</HEAD>

<BODY>

    <?php

    $filename = "test.txt" ;

    $chaine = "Commandes des Composants Electroniques de chez Jean-Pierre\t" ;

    // Assurons-nous que le fichier est accessible en écriture

    if ( is_writable ( $filename )) {

    // Dans notre exemple, nous ouvrons le fichier variable $filename en mode d'ajout

    // Le pointeur de fichier est placé à la fin du fichier

    // C'est là que le fichier $chaine sera placé

    if (! $manipuler = fopen ( $filename , "a" )) {

    echo "<B> <BR> <BR> <font face=Arial size=3 color=#800000>Impossible d'ouvrir le fichier ( $filename ) </font> </B>" ;

    exit;

    }

    // Ecrivons quelque chose dans notre fichier.

    if ( fwrite ( $manipuler , $chaine ) === FALSE ) {

    echo "<B> <BR> <BR> <font face=Arial size=3 color=#800000>Impossible d'&eacute;crire dans le fichier ( $filename ) </font> </B>" ;

    exit;

    }

    echo "<B> <BR> <BR> <font face=Arial size=3 color=#800000>L'&eacute;criture de ( $chaine ) dans le fichier ( $filename ) a r&eacute;ussi. </font> </B>" ;

    fclose ( $manipuler ); // Fermeture du fichier.

    }

    else

    {

    echo "<B> <BR> <BR> <font face=Arial size=3 color=#800000>Le fichier $filename n'est pas accessible en &eacute;criture. </font> </B>" ;

    }

    ?>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2]. Et pour visualiser le fichier Test, en cliquant ici.

Cette instruction notifiée en couleur rouge claire, à l'interpréteur PHP qu'il doit écrire la chaîne stockée dans la variable $chaine dans le fichier pointé par $manipuler. Avant de discuter du contenu de la variable $chaine, nous allons nous pencher plus en détail sur la fonction fwrite().

Arguments de la fonction fwrite() :

La fonction fwrite() prend trois arguments, dont le troisième est optionnel. Le prototype de fwrite() est la suivante :

    int fputs (int fp, string chaîne, int[longeur]) ;

Le troisième paramètre, longueur, spécifie le nombre maximal d'octets à écrire. Lorsque ce paramètre est fourni, la fonction fwrite() écrit la valeur du paramètre chaîne dans le fichier pointé par le paramètre fp, jusqu'à atteindre la fin de chaine, ou jusqu'à avoir écrit le nombre d'octets spécifiés dans longueur.

Formats de fichiers :

Lors de la création d'un fichier de données tel que celui créé dans notre exemple, le choix du format de stockage des données vous appartient (bien sûr, si vous prévoyez d'utiliser le fichier de données avec une autre application, vous devez en tenir compte dans votre choix).

Construisons une chaîne représentant un enregistrement de notre fichier de données, comme suit :

    $date = date ("d / m / Y, H : i : s") ;

    $Prenom = $numnames ;

    $Nom = $numnames_2 ;

    $chaine = $date . "\t |" . $ResisQty . "\t | " . $CondosQty

    . "\t | " . $TransisQty . "\t |" . $Prenom . "\t |" . $Nom . "\t |" . $Adresse . "\t" ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3]. Et pour visualiser le fichier Test, en cliquant ici.

Dans cet exemple simple, chaque commande est stockée dans une ligne séparée du fichier de commande. L'écriture d'un enregistrement par ligne nous permet, en effet de disposer d'un séparateur d'enregistrement simple : le caractère de nouvelle ligne. Les caractères de nouvelle ligne sont invisibles, et doivent être représentés avec la séquence de contrôle "\n".

Pour chaque nouvelle commande, les champs de données sont écrits dans le même ordre, et sont séparés entre eux part le caractère de tabulation, représenté par la séquence de contrôle "\t". Mieux vaut choisir des délimiteurs de champs qui soient ensuite facile à lire.

Le séparateur et le délimiteur doivent être des caractères peu susceptibles d'être contenus dans les données des champs. Il est également possible de traiter les données à écrire dans le fichier, de sorte à en retirer ou à échapper à toute instance du délimiteur ou du séparateur. Nous reviendrons sur le traitement des données saisies dans les prochaines leçons. Pour l'heure, nous supposerons qu'aucun client n'a introduit de tabulation au cours de sa saisie dans le formulaire de commande. Pour l'utilisateur d'un formulaire HTML, il est difficile, mais pas impossible, d'insérer une tabulation ou un caractère de nouvelle ligne dans un champ de saisie HTML à une seule ligne.

En utilisant un séparateur de champ spécial, nous pourrons par la suite scinder plus facilement les données en variable séparées, lorsque nous voudrons lire les données contenues dans le fichier. Nous reviendrons sur ce point au cours de nos leçons. Pour l'instant, nous nous contenterons de traiter chaque commande en tant que chaîne unique.

Le listing de la fiure 3 donne un exemple de contenu du fichier Test_2.txt après écriture de quelques commandes.

Fermeture d'un fichier :

Une fois que vous en avez fini avec un fichier, vous devez le fermer au moyen de la fonction fclose(), comme suit :

    fclose ($manipuler) ;

La fonction fclose() renvoie la valeur true lorsque la fermeture du fichier a réussi, ou false en cas d'échec. Le risque d'échec étant moins grand pour une opération de fermeture de fichier que pour une opération d'ouverture de fichier, nous avons choisi dans ce cas de ne pas implémenter de test.

Problèmes d'ouverture de fichiers :

Une des erreurs les plus fréquemment commises à l'ouverture des fichiers, consiste à essayer d'ouvrir un fichier sans bénéficier de la permission adéquate. Dans une telle situation d'erreur, PHP envoie un avertissement tel que ci-après : Permission denied ce qui signifie en français ; permission refusée.

Face à une telle erreur, vous devez vérifier que l'utilisateur qui représente le script exécuté bénéficie de la permission d'accès adéquate au fichier que vous voulez manipuler. Selon la manière dont est configuré votre serveur, le script peut être exécuté en tant qu'utilisateur du serveur Web, ou bien en tant que propriétaire contenant le script.

Dans la plupart des systèmes, les scripts sont exécutés en tant qu'utilisateur du serveur Web. Dans ce cas, il vous faudrait créer un dossier en écriture universelle pour le stockage de la commande, en exécutant la commande suivante :

    mkdir ~ /Automobile

    chmod 777 ~ /Automobile

Gardez bien à l'esprit le danger que constituent les dossiers et les fichiers dans lesquels tout un chacun peut écrire. Vous devez impérativement éviter d'autoriser l'écriture dans des dossiers directement accessibles à partir du Web. C'est pour cette raison que dans certains exemples donnés ici, donc, certains dossiers se situent à deux sous-dossiers en amont. Nous aborderons plus en détail cet aspect de sécurité dans les prochaines leçons.

Si un mauvais paramétrage des permissions d'accès constitue l'erreur la plus commune lors de l'ouverture d'un fichier, d'autres erreurs peuvent également être commises. Lorsqu'un fichier ne peut être ouvert, il est capital que vous en soyez informé, pour éviter de tenter d'y lire ou d'y écrire des données.

Lecture dans un fichier :

A ce stade de notre projet modèle, les clients de chez Jean-Pierre peuvent transmettre leurs commandes via le Web. Pour que les employés de chez Jean-Pierre puisse traiter ces commandes, nous devons toutefois encore implémenter une interface Web qui leur permette d'ouvrir et de lire facilement les fichiers contenant les commandes, comme dans les exemples 2 et 3. Le code de cette interface est donné dans le listing, comme suit :

<HTML>

<HEAD>

<TITLE> Les Composants &Eacute;lectroniques de chez Jean-Pierre </TITLE>

</HEAD>

<BODY>

<BR> <BR>

<h1>&nbsp;&nbsp;&nbsp;&nbsp;Les Composants &Eacute;lectroniques de chez Jean-Pierre</h1>

<h2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bon de commandes</h2>

<?PHP

@ $fp = fopen ("Orders/Commandes.txt", "r") ;

if (!$fp)

{

echo "<p> <strong> N&deg; de Commande . \t" . "Veuillez r&eacute;essayer plus tard </strong> </p>" ;

exit ;

}

while (!feof($fp)) // File End Of File, Cette boucle test si la fin du fichier est atteinte

{

$char = fgets($fp, 100); // Lit le contenu du fichier ligne par ligne

if (!feof($fp))

echo ($char == "\n" ? "<br>" : $char) ; // ? = ternaire

}

fclose($fp);

// On teste les diff&eacute;rentes valeurs

if (isset($_FILES['mon_fichier']))

// On affiche ces diff&eacute;rentes valeurs

echo '<BR> Nom d\'origine : ' . $_FILES['mon_fichier']['name'] .' <br/>' ;

echo 'Taille : ' . $_FILES['mon_fichier']['size'] .' <br/>' ;

echo 'Type de fichier : '. $_FILES['mon_fichier']['type'] .'<br/>' ;

echo 'Code erreur : '. $_FILES['mon_fichier']['error'] .'<br/>' ;

?>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Ce script met en oeuvre la série d'opérations évoquée précédemment : ouverture du fichier, lecture dans le fichier, et fermeture du fichier. L'exécution de ce script avec le fichier de données décrit, en exemple 4, produit le même résultat montré à la figure 3, ci-dessus.

Examinons, en détail les différentes fonctions utilisées dans ce script sur une autre page afin de ne pas encombrer celle-ci.

Fin de ce premier chapitre, le prochain sera consacré "aux fonctions fopen(), feof(), fgets(), fgetss(), fgetcsv(), reafile() et fpassthru(), file(), etc. ..." qui sera la suite de cette leçon".


Utilisation des Instructions require() et include()

Utilisation des Instructions require() et include() et Utilisation des Options de Configuration "auto_prepend_file" et "auto_append_file" (1ère partie) :

Cette leçon explique comment réutiliser du code pour développer des applications plus cohérentes, plus fiables et plus faciles à gérer, avec moins d'efforts. Nous examinerons des techniques de modularisation et de réutilisation du code, à commencer par la simple mise en oeuvre des fonctions require() et include() pour utiliser le même code dans plusieurs pages. Nous expliquerons pourquoi cette technique est plus efficace que le scriptage côté serveur. Cette leçon donne un exemple qui montre bien comment l'utilisation de fichiers include permet d'obtenir une apparence cohérente sur tout un site Web.

Nous verrons également comment écrire et invoquer des fonctions utilisateur, en illustrant nos propos par des exemples de fonctions permettant de générer des pages et des formulaires.

Intérêt d'une réutilisation du code :

Nombre d'Ingénieurs du génie logiciel cherchent à réutiliser du code au lieu d'en écrire du nouveau. Non pas que les développeurs soient particulièrement paresseux, mais la réutilisation de code existant tend à réduire les coûts, à augmenter la fiabilité des programmes, et à améliorer leur cohérence. Dans l'idéal, un nouveau projet devrait être conduit, en combinant des composants logiciels réutilisables existants, avec un minimum de développement à la source.

Cohérence :

Les interfaces externes en usage dans un système, y compris les interfaces utilisateur et les interfaces vers des systèmes externes, doivent être cohérentes. Il faut de l'opiniâtreté et des efforts délibérés pour écrire du nouveau code qui reste cohérent avec les autres parties du système. Par contre, si vous réutilisez du code déjà en service dans une autre part du système, vous avez toutes les chances pour que la fonctionnalité obtenue soit automatiquement cohérente.

Réutiliser du code minimise la charge de travail du développeur, à condition que le code d'origine soit modulaire et bien écrit, et c'est là un avantage majeur de la réutilisation de code. Lors de vos travaux de développement logiciel, attachez-vous à identifier les sections de votre code susceptible de servir ultérieurement dans d'autres applications.

Utilisation des instructions require() et include() :

Le langage PHP offre deux instructions très simples, et néanmoins très utiles, qui permettent de réutiliser tout type de code. Par le biais d'une instruction require() ou include(), vous pouvez charger un fichier dans un script PHP. Le fichier ainsi chargé peut contenir tout ce qui pourrait normalement être inclus dans un script, y compris des instructions PHP, du texte, des balises HTML, des fonctions PHP, ou des classes PHP.

Les instructions require() et include() fonctionnent à la manière des "includes" côté serveur offerts par nombre de serveurs Web, et aux instructions #include des langages C et C++.

Utilisation de la fonction require() :

Soit les fichiers dénommés Reutilisable.php et Principal.php. Supposez que le fichier Reutilisable.php contienne le code suivant :

    <?php

    echo "<BR/> <H2> &nbsp;&nbsp;&nbsp;&nbsp; Voici une d&eacute;claration de PHP tr&egrave;s simple du fichier Reutilisable.php ! </H2> <BR/>" ;

    ?>

Pour visualiser l'aperçu du fichier Réutilisable.php, en cliquant ici. [Exemple 1].

Et que le fichier Principal.php ait le contenu suivant :

    <?php

    echo "<BR/> <H2> <font color='#005500'> &nbsp;&nbsp;&nbsp;&nbsp; Ceci est le fichier Principal.php ! </font> </H2> <BR/>" ;

    require ("Reutilisable.php") ;

    echo "<BR/> <H2> <font color='#005500'> &nbsp;&nbsp;&nbsp;&nbsp; Le script se terminera jusqu'ici du fichier Principal.php ! </font> </H2>" ;

    ?>

Pour visualiser l'aperçu du fichier Principal.php, en cliquant ici. [Exemple 1 bis].

Au chargement du fichier Reutilisable.php, vous verrez apparaître dans votre navigateur Web la phrase suivante : "Voici une déclaration de PHP très simple du fichier Reutilisable.php !", ce qui ne devrait probablement pas vous surprendre. Par contre, le chargement du fichier Principal.php à un effet un peu plus inattendu. Le résultat obtenu est montré à la figure 1.

La mise en oeuvre d'une instruction require() exige un fichier. Dans l'exemple précédent, nous avons utilisé le fichier dénommé Reutilisable.php. A l'exécution du script, l'instruction require() :

    require ("Reutilisable.php") ;

est remplacée par le contenu du fichier spécifié, et le script contenu dans ce dernier est alors exécuté. L'exécution qui s'opère au chargement du fichier Principal.php est donc équivalente à l'exécution du script suivant :

    <?php

    echo "<BR/> <H2> <font color='#005500'> &nbsp;&nbsp;&nbsp;&nbsp; Ceci est le fichier Principal.php ! </font> </H2> <BR/>" ;

    echo "<BR/> <H2> &nbsp;&nbsp;&nbsp;&nbsp; Voici une d&eacute;claration de PHP tr&egrave;s simple du fichier Reutilisable.php ! </H2> <BR/>" ;

    echo "<BR/> <H2> <font color='#005500'> &nbsp;&nbsp;&nbsp;&nbsp; Le script se terminera jusqu'ici du fichier Principal.php ! </font> </H2>" ;

    ?>

Pour bien utiliser l'instruction require(), vous devez connaître les différents modes de gestion des extensions de noms de fichier et des balises PHP.

La fonction require() et les extensions de noms de fichier :

PHP ignore l'extension du nom du fichier chargé au moyen de la fonction require(). Par conséquent, vous pouvez donner à ce fichier le nom qui vous convient, si tant est que vous ne l'invoquez pas directement. Lorsque la fonction require() est mise en oeuvre pour charger un fichier, celui-ci devient partie intégrante d'un fichier PHP, et est exécuté en tant que tel.

Des instructions PHP stockées dans un fichier appelé, par exemple, page.html, ne sont normalement pas traitées. L'interpréteur PHP ne traite normalement que les fichiers dont les noms portent des extensions définies, telles que .php. Toutefois, si le fichier page.html est chargé via la fonction require(), toute instruction PHP contenue dans ce fichier sera traité par l'interpréteur PHP. Par conséquent, vous pouvez choisir n'importe quelle extension pour les fichiers à inclure via require(). Il est toutefois recommandé de s'en tenir à une convention logique pour le choix des noms de fichier (par exemple, en adoptant systématiquement l'extension .inc pour tous les fichiers à inclure).

Lorsque des fichiers portant une extension non standard, telle que .inc, sont stockés dans une arborescence de documents Web, les utilisateurs qui les chargent directement dans leur navigateur peuvent visualiser leur contenu en plein texte, y compris les mots de passe qui y sont éventuellement spécifiés. Par conséquent, il est très important de stocker ce type de fichier hors de l'arborescence de documents, ou bien alors d'employer des extensions standard.

La fonction require() et les balises PHP :

Dans l'exemple considéré plus haut de cette leçon, le fichier Reutilisable.php avait le contenu suivant :

    <?php

    echo "<BR/> <H2> &nbsp;&nbsp;&nbsp;&nbsp; Voici une d&eacute;claration de PHP tr&egrave;s simple du fichier Reutilisable.php ! </H2> <BR/>" ;

    ?>

Le code PHP stocké dans le fichier est encadré par des balises PHP. L'usage de balises PHP est indispensable pour que le code d'un fichier chargé via la fonction require() soit traité par l'interpréteur PHP. En l'absence de balise PHP, le code sera considéré comme du texte ou du code HTML, et ne sera pas exécuté.

Utilisation de la fonction require() pour des modèles de site Web :

Lorsqu'un site Web doit être conçu avec une présentation et un style cohérent sur toutes les pages, la fonctions PHP require() peut être utilisée pour ajouter un même modèle et des éléments standard à toutes les pages.

Par exemple, considérons le cas d'une entreprise fictive, dénommée CEI "Consultant Électronique-Informatique", dont le site contient tout un jeu de pages ressemblant à la page de la figure 2.

Lorsqu'une nouvelle page doit être ajoutée au site, le développeur peut ouvrir une page existante, effacer le texte contenu dans le milieu du fichier, entrer un nouveau texte, puis enregistrer le fichier sous un nouveau nom.

Considérez le scénario suivant : le site Web est en service depuis un certain temps déjà, et contient à présent des centaines, voire des milliers de pages, toutes construites sur le même style. Supposez qu'il soit décidé de procéder à une modification de l'apparence standard, même mineure, comme l'ajout d'une adresse de courrier électronique en bas de chaque page, ou d'une nouvelle entrée dans le menu de navigation. Voulez-vous vous trouver dans la situation de devoir modifier des centaines, voire des milliers de pages ?

La réutilisation des sections HTML communes à toutes les pages est de loin préférable à des opérations de couper/coller à reproduire sur des centaines ou des milliers de pages. Le code source de la page d'accueil montrée à la figure 2 correspond au Listing ci-dessous :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Le Listing de l'exemple 2, se compose de plusieurs sections de code bien distinctes. L'en-tête HTML contient les définitions d'une feuille de style CSS (Cascading Style Sheet) utilisées dans la page. La section intitulée "Page header" conduit à l'affichage du nom et du logo de l'entreprise, la section "Menu bar" crée la barre de navigation de la page, tandis que la section "Page Content" ou ("le contenu de la page") rassemble le texte spécifique à cette page. Vient ensuite, le Pied de page ou (page footer). Nous allons scinder ce fichier en trois parts, que nous stockerons respectivement dans les fichiers Header.inc, Home.php et Footer.inc. Les fichiers Header.inc et Footer.inc contiendront alors du code que nous réutiliserons pour générer d'autres pages.

Le fichier Home.php vient en remplacement du fichier Home.html, et contient le contenu textuel spécifique de la page, ainsi que deux instructions require(). Le contenu de ce fichier est présenté au Listing ci-après :

Les instructions require() du listing ci-dessus provoquent le chargement des fichiers Header.inc et Footer.inc.

Comme nous l'avons déjà mentionné, les noms attribués à ces fichiers n'ont pas d'incidence sur la manière dont les fichiers sont traités, lorsque le chargement s'effectue via une instruction require(). L'extension .inc (pour "inclure", ou "include") est très souvent adoptée pour ce type de fichiers, qui sont appelés à être inclus dans d'autres fichiers. Cette convention, bien que très répandue, est entièrement optionnelle. Par ailleurs, l'usage est généralement de rassembler les fichiers include dans un dossier visible des scripts, mais qui ne permette pas le chargement individuel des fichiers via le serveur Web. Cette pratique est fortement recommandée. En effet, le chargement individuel de ces fichiers peut provoquer des erreurs si l'extension des fichiers est .php, et que les fichiers ne contiennent que des pages ou des scripts partiels, ou peut permettre à des tiers de lire le code source lorsqu'une extension autre que .php est employée.

Le fichier Header.inc contient les définitions d'une feuille de style CSS utilisées par la page, ainsi que les tableaux qui affichent le nom de l'entreprise et les barres de navigation. Son contenu est donné dans le Listing ci-après :

Le fichier Footer.inc contient le tableau utilisé pour afficher le pied de page, en bas de chaque page. Le Listing ci-après montre le contenu de ce fichier :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Une telle approche permet d'obtenir facilement une présentation et une apparence homogènes sur tout un site. Une nouvelle page conçue dans le même style peut être aisément générée en quelques lignes de code, par exemple :

    <?PHP

    require ("header.inc") ;

    ?>

    voici le contenu de cette page

    <?PHP

    require ("footer.inc") ;

    ?>

Plus important encore, même lorsque de nombreuses pages ont ainsi été générées à partir des mêmes fichiers d'en-tête et de pied de page, vous pouvez facilement modifier ces fichiers modèles. Que la modification apportée soit mineure, ou qu'elle vise à donner une apparence complètement nouvelle au site, elle ne devra être apportée qu'une seule fois. Cette technique évite d'avoir à traiter chaque page séparément.

Dans l'exemple considéré ici, le corps, l'en-tête et le pied de page de chaque page ne contiennent que du plein HTML. Des instructions PHP peuvent toutefois très bien être utilisées, de sorte à générer dynamiquement certaines parties des pages Web du site.

Utilisation des options de configuration auto_prepend_file et auto_append_file :

Il existe une autre manière d'utiliser l'instruction require() pour ajouter un en-tête et un pied de page à chaque page. Le fichier de configuration php.ini contient deux options de configuration, auto_prepend_file et auto_append_file, qui peuvent être ajustées sur nos fichiers d'en-tête et de pied de page, de sorte que ces fichiers soient systématiquement chargés avant et après chaque page.

Dans un système Windows, le réglage de ces options s'effectuerait de la manière suivante :

    auto_prepend_file = "c:/inetpub/include/header.inc"

    auto_append_file = "c:/inetpub/include/footer.inc"

Sur une plate-forme Unix, ces options se régleraient comme suit :

    auto_prepend_file = "/home/username/include/header.inc"

    auto_apend_file = "/home/username/include/footer.inc"

Lorsque ces directives sont spécifiées dans le fichier php.ini, il n'est plus nécessaire d'implémenter des instructions require(). Par contre, les en-têtes et pieds de page ne sont plus optionnels dans les pages Web.

Avec un serveur Web Apache, vous pouvez ajuster diverses options de configuration comme celles décrites précédemment, pour chaque dossier individuel. Pour cela, vous devez configurer votre serveur de sorte que ces principaux fichiers de configuration soient "écrasables". Pour configurer PHP de sorte à charger automatiquement des fichiers avant et après chaque page, pour un dossier spécifique, créez dans ce dossier un fichier appelé .htaccess. Incluez dans ce fichier les deux lignes suivantes :

    php_value auto_prepend_file "/home/username/include/header.inc"

    php_value auto_apend_file "/home/username/include/footer.inc"

Notez que cette formulation diffère légèrement du paramétrage décrit plus haut pour le fichier php.ini. Divers autres paramètres de configuration peuvent être insérés de la sorte dans ce fichier.

Ce prototype a changé depuis la version 3 de PHP. Si vous utilisez une ancienne version de PHP, les lignes insérées dans votre fichier .htaccess doivent être du type comme suit :

    php3_auto_prepend_file "/home/username/include/header.inc"

    php3_auto_apend_file "/home/username/include/footer.inc"

L'ajustement d'options dans le fichier .htaccess et non pas dans le fichier php.ini ou dans le fichier de configuration du serveur Web, amène une grande flexibilité. Vous pouvez ainsi modifier le paramétrage sur une machine partagée, en n'affectant que vos seuls dossiers. Il n'est pas nécessaire de redémarrer le serveur Web, ni de bénéficier d'un accès administrateur système. L'approche .htaccess a toutefois l'inconvénient que les fichiers sont lus et analysés chaque fois qu'un fichier est sollicité dans le dossier concerné, au lieu d'être lus et analysés une seule fois au démarrage. Elle se traduit donc par une baisse de performance

Utilisation de la fonction include() :

Les instructions require() et include() sont très similaires, mais leurs modes de fonctionnement diffèrent sur des points importants.

Une instruction include() est évaluée chaque fois que le bloc de code la contenant est exécuté, et n'est pas du tout évaluée si le bloc de code n'est pas exécuté. Par contre, une instruction require() est exécutée dès lors qu'elle est analysée par l'interpréteur PHP, même si le bloc de code la contenant n'est pas exécuté.

A moins que le serveur Web ne soit très occupé, cette différence de fonctionnement n'a pas d'effet notable. Elle a toutefois pour conséquence que les instructions require() implémentées au sein de structures conditionnelles sont inefficaces.

    if ($Variable == true)

    {

        require ("file_1.inc") ;

    }

    else

    {

        require ("file_2.inc") ;

    }

Ce code conduit au chargement de chacun des deux fichiers spécifiés à chaque exécution du script, un seul étant utilisé, en fonction de la valeur de la $Variable. Par contre, ce code implémenté avec des instructions include() conduirait au chargement et à l'utilisation d'un seul des deux fichiers comme suit :

    if ($Variable == true)

    {

        include ("file_1.inc") ;

    }

    else

    {

        include ("file_2.inc") ;

    }

Contrairement au cas de fichiers chargés via une instruction require(), une instruction include() employée pour charger un fichier peut renvoyer une valeur. D'autres parties d'un programme peuvent alors être notifiées du succès ou de l'échec du chargement du fichier "include".

Considérons le cas d'une application où de nombreuses ouvertures de fichiers sont nécessaires. Nous pourrions choisir, au lieu de retaper les mêmes lignes de code chaque fois, d'utiliser un fichier "include" pour charger automatiquement les fichiers requis.

Nous pourrions dénommer ce fichier "include" OpenFile.inc, et y insérer le contenu suivant :

    <?PHP

    $fp = fopen ("$name", "$mode");

    if (!$fp)

    {

    echo "<p> <strong> Oh non ! Impossible d'ouvrir le fichier. $fp </strong> </p>" ;

    return 0 ;

    }

    else

    {

    return 1 ;

    }

    fclose($fp) ;

    ?>

Ce code tente d'ouvrir le fichier dénommé $name, selon le mode défini par $mode. En cas d'échec, un message d'erreur est généré, et la valeur 0 est renvoyée. En cas de succès, la valeur 1 est renvoyée, sans qu'aucun message ne soit affiché.

Le fichier OpenFile.php pourrait être chargé au moyen du script suivant :

    <?PHP

    $name = "test_4.txt" ;

    $mode = "r" ;

    $result = include("OpenFile.inc") ;

    if (!$result == 1)

    {

    // faire ce qu'il y a &agrave; faire avec le fichier

    // Se r&eacute;ferrer &agrave; la variable $fp crée dans le fichier include

    }

    ?>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Notez que les deux variables $name et $mode créées dans le fichier principal, et celles créées dans le fichier "include", existent dans les deux fichiers. Ce comportement vaut à la fois pour les fonctions require() et pour include().

L'instruction require() ne pourrait convenir dans le cas de figure précédent, parce qu'elle ne renvoie pas de valeur. Le renvoi d'une valeur peut se révéler très utile, dans la mesure où il permet de notifier des parties ultérieures du script de l'occurrence d'une erreur, ou d'effectuer des traitements indépendants et de renvoyer une réponse. Les fonctions constituent un meilleur moyen encore que les fichiers "include", pour scinder du code en modules autonomes. La suite de cette leçon leur est consacrée que l'on verra plus loin dans ce même chapitre.

Malgré les avantages que présente l'instruction include() sur l'instruction require(), celle-ci est bien plus utilisée, du fait de sa plus grande rapidité.

Pour l'instant, nous terminons ce premier chapitre et nous verrons dans le prochain, l'usage de fonctions en PHP, invocation de fonctions, définir ses propres fonctions également et d'une structure de base d'une fonction ainsi que les paramètres.


Utilisation des Tableaux en PHP

Utilisation de tableaux, Tableaux indexés numériquement, Tableaux associatifs, Tableaux multidimensionnels, etc. (1ère partie) :

Utilisation de tableaux :

Cette nouvelle leçon montre comment utiliser une construction de programmation importante : les tableaux. Les variables examinées dans les leçons précédentes étaient de nature scalaire, c'est-à-dire qu'elles stockaient chacune une seule valeur. Un tableau est une variable stockant un ensemble ou une série de valeurs. Un même tableau peut comprendre de nombreux éléments. Chaque élément peut lui-même se constituer d'une valeur unique, telle qu'un texte ou un nombre, ou d'un autre tableau. Un tableau comprenant d'autres tableaux est dit "multidimensionnel".

Le langage PHP supporte les tableaux indexés numériquement et les tableaux associatifs. Les tableaux indexés numériquement devraient vous être familiers si vous avez déjà utilisé un langage de programmation. Par contre, à moins que vous n'ayez déjà pratiqué la programmation PHP ou Perl, vous n'avez probablement jamais encore eu recours à des tableaux associatifs. Les tableaux associatifs permettent d'utiliser des valeurs plus utiles pour l'index, par exemple des mots ou d'autres informations significatives.

Dans cette leçon, nous poursuivrons la construction de l'application modèle de chez Jean-Pierre commencée dans les leçons précédentes, en nous servant de tableaux pour faciliter la manipulation des informations répétitives telles que les commandes client. L'usage de tableaux nous permettra d'écrire un code plus dense pour certaines des opérations déjà implémentées dans les deux premières leçons.

Qu'est-ce qu'un tableau ?

Dans la première leçon, nous avons étudié les variables scalaires à l'exemple 3, en cliquant ici . Une variable scalaire est un emplacement de la mémoire désigné par un nom, et dans lequel peut être stockée une valeur. De la même manière, un tableau est un emplacement de la mémoire désigné par un nom, et dans lequel peut être stocké un ensemble de valeurs. Un tableau permet par conséquent de regrouper des valeurs scalaires.

Dans l'application modèle des composants électroniques de chez Jean-Pierre, dont nous avons commencé l'élaboration, nous utiliserons un tableau pour stocker la liste des articles de chez Jean-Pierre. La figure 1 montre une liste de trois articles regroupés dans un tableau. La variable $Produits est utilisée pour stocker ce tableau (nous verrons un peu plus loin comment créer une telle variable).

Dès lors que des informations sont stockées dans un tableau, elles peuvent être soumises à diverses manipulations très utiles. En mettant en oeuvre des boucles telles que celles décrites à la première leçon (en cliquant ici), vous pouvez vous simplifier la tâche en effectuant les mêmes actions sur chacune des valeurs d'un tableau. L'ensemble des informations enregistrées dans un tableau peut être manipulé comme s'il s'agissait d'une seule entité. Ainsi, avec une simple ligne de code, toutes les valeurs contenues dans un tableau peuvent être passées à une fonction. Par exemple, pour trier les articles de chez Jean-Pierre par ordre alphabétique, il nous suffira de passer le tableau les contenant à la fonction PHP sort().

Les valeurs stockées dans un tableau constituent les "éléments" du tableau. A chaque élément d'un tableau est associé un "index" (également appelé "clé") qui permet d'accéder à l'élément.

Dans la plupart des langages de programmation, les tableaux ont des index numériques qui commencent typiquement à 1 ou à 0. PHP supporte ce type de tableaux.

PHP supporte également les tableaux dits "associatifs", familiers aux programmeurs Perl. Les index des tableaux associatifs peuvent être construits à partir de presque tout type de données, mais sont typiquement construits à partir de chaînes.

Nous commencerons cette étude par les tableaux indexés numériquement.

Tableaux indexés numériquement :

Ce type de tableau est supporté par la grande majorité des langages de programmation. En PHP, les index commencent par défaut à zéro, mais cette valeur initiale peut être ajustée.

Initialisation de tableaux indexés numériquement :

Pour créer le tableau schématisé figure 1, vous devez utiliser la ligne de code suivante :

    $Produits = array ("Resistanses", "Condensateurs", "Transistors") ;

L'exécution de cette instruction conduit à la création d'un tableau appelé $Produits, et contenant les trois valeurs "Resistances", "Condensateurs", et "Transistors". Notez que tout comme echo, array() est une construction du langage plutôt qu'une fonction.

Selon le contenu à stocker dans un tableau, il n'est pas forcément nécessaire d'initialiser manuellement ce contenu comme cela est fait dans l'instruction précédente.

Si les données à placer dans un tableau sont déjà contenues dans un autre tableau, il suffit de copier un tableau dans l'autre au moyen de l'opérateur = (affectation).

Une série de nombres croissants peut être automatiquement stockée dans un tableau grâce à la fonction range(), qui se charge elle-même de créer le tableau requis. La ligne qui suit crée un tableau dénommé $Nombres, et dont les éléments sont les nombres entiers compris entre 1 et 10 :

    $Nombres = range (1, 10) ;

Lorsque des informations sont contenues dans un fichier stocké sur disque, le contenu du tableau peut être directement chargé à partir du fichier. Nous reviendrons sur ce point un peu plus loin dans cette leçon, dans la section "chargement de tableaux à partir de fichiers".

Lorsque des informations sont contenues dans une base de données, le contenu du tableau peut être directement chargé à partir de la base de données. Cette possibilité est traitée plus loin concernant les nouvelles leçons.

Le langage PHP offre également diverses fonctions permettant d'extraire des portions d'un tableau ou de réorganiser le contenu des tableaux. Certaines de ces fonctions seront décrites plus loin de cette leçon.

Accès au contenu des tableaux :

L'accès au contenu d'un tableau implique de spécifier le nom du tableau. Pour accèder au contenu d'une variable de type tableau, vous devez utiliser le nom de la variable, ainsi qu'une clé (ou un index). La clé indique les valeurs stockées auxquelles vous voulez accéder. La clé doit être spécifiée entre crochets, juste après le nom de la variable.

Par exemple, tapez $Produits[0], $Produits[1], et $Produits[2] pour accéder au contenu du tableau $Produits.

L'élément zéro est le premier élément du tableau. Le principe de numérotation du langage PHP est identique à celui de nombreux autres langages de programmation tels que le C, le C++, ou Java. Si toutefois, vous ne connaissez aucun de ces langages, il vous faudra peut-être un peu de temps pour vous familiariser.

Tout comme pour les autres variables, la modification du contenu des éléments d'un tableau s'effectue au moyen de l'opérateur =. La ligne de code qui suit remplace le premier élément du tableau $Produits, "Resistances", par l'élément "Fusibles" :

    $Produits[0] = "Fusibles" ;

L'instruction qui suit pourrait être utilisée pour ajouter un nouvel élément, "Fusibles", à la fin du tableau, conduisant ainsi à un tableau $Produits formé de quatre éléments :

    $Produits[3] = "Fusibles" ;

Pour afficher le contenu du tableau $Produits, nous pourrions utiliser la ligne de code suivante :

    echo "$Produits[0] $Produits[1] $Produits[2] $Produits[3]" ;

Tout comme les autres variables PHP, les tableaux ne nécessitent pas une initialisation ou une création préalables. Ils sont automatiquement créés à leur première utilisation.

Le code qui suit conduit à la création du même tableau $Produits que celui déjà cité :

    $Produits[0] = "Resistances" ;

    $Produits[1] = "Condensateurs" ;

    $Produits[2] = "Transistors" ;

Si le tableau $Produits n'existe pas encore, la première ligne crée un nouveau tableau formé d'un élément. Les lignes qui suivent, ajoutent des valeurs au tableau qui vient dêtre créé.

Utilisation de boucles pour accéder au contenu d'un tableau :

Lorsqu'un tableau est indexé par une série de nombres, une boucle for peut être mise en oeuvre pour afficher plus facilement le contenu du tableau.

    for ($i = 0; $i <3; $i++)

    echo "$Produits[$i]" ;

<HTML>

<HEAD>

<TITLE> Boucles pour acc&eacute;der au contenu d'un tableau </TITLE>

</HEAD>

<BODY>

<?php

echo "<BR/> <BR/> <CENTER>" ;

$Produits[0] = "&nbsp;&nbsp;&nbsp;&nbsp;<font face='Arial' size='3' color='#000000'>R&eacute;sistances </font> <BR/>" ;

$Produits[1] = "&nbsp;&nbsp;&nbsp;&nbsp;<font face='Arial' size='3' color='#000000'>Condensateurs </font> <BR/>" ;

$Produits[2] = "&nbsp;&nbsp;&nbsp;&nbsp;<font face='Arial' size='3' color='#000000'>Transistors </font> <BR/> </CENTER>" ;

for ($i = 0 ; $i < 3 ; $i++)

echo "$Produits[$i]" ;

?>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Dans cette boucle (de couleur verte foncée) produit un tableau identique à celui obtenu par exécution des trois dernières instructions de la section précédente, tout en étant plus compact. La possibilité d'utiliser ainsi une simple boucle pour accéder à chaque élément d'un tableau est une élégante particularité des tableaux indexés numériquement. Dans les tableaux associatifs, il n'est pas si facile de parcourir le contenu au moyen de boucles. Par contre, les tableaux associatifs ont l'avantage de permettre la constitution d'index significatifs.

Tableaux associatifs :

Dans le tableau $Produits, nous avons laissé à l'interpréteur PHP le soin d'indexer les éléments du tableau. C'est ainsi que le premier élément s'est vu associer la clé 0, le deuxième élément la clé 1, et ainsi de suite. PHP supporte également les tableaux associatifs, dans lesquels toute clé peut être associée à chaque valeur.

Initialisation d'un tableau associatif :

L'instruction qui suit conduit à la création d'un tableau associatif dont les noms des articles sont les clés et dont les prix sont les valeurs :

    $Prix = array( "Resistances" =>2, "Condensateurs" =>3, "Transistors =>5 ) ;

Accès aux éléments du tableau :

Là encore, l'accès au contenu du tableau s'effectue en spécifiant le nom de la variable et une clé. Ainsi, pour accéder au tableau créé par l'instruction de la section précédente, nous utiliserions les expressions $Prix ["Resistances"], $Prix ["Condensateurs"], et $Prix ["Transistors"].

Tout comme les tableaux indexés numériquement, les tableaux associatifs peuvent être créés et initialisés par un élément à la fois.

Les lignes de code qui suivent, conduisent à la création du même tableau $Prix que celui déjà créé. Au lieu toutefois de générer d'emblée un tableau formé de trois éléments, cette version crée tout d'abord un tableau comprenant un élément, puis lui ajoute deux éléments supplémentaires.

    $Prix = array( "Resistances" => 2 ) ;

    $Prix["Condensateurs"] = 3 ;

    $Prix["Transistors"] = 5 ;

Considérons à présent une autre variante de ce fragment de code, dont l'exécution produit un résultat identique. Ce code ne génère pas explicitement un tableau, mais conduit indirectement à la création d'un tableau lorsqu'un premier élément est ajouté à un tableau encore inexistant.

    $Prix["Resistances"] = 2 ;

    $Prix["Condensateurs"] = 3 ;

    $Prix["Transistors"] = 5 ;

Implémentation de boucles utilisant les fonctions each() et list() :

Parce que dans le tableau associatif généré précédemment, les clés ne sont pas des nombres, la manipulation du tableau ne peut s'effectuer en implémentant une boucle for avec un compteur simple. Le fragment de code qui suit, liste le contenu du tableau $Prix :

<HTML>

<HEAD>

<TITLE> Boucles pour acc&eacute;der au contenu d'un tableau </TITLE>

</HEAD>

<BODY>

    <?PHP

    $Prix = array ("R&eacute;sistances" => 2 ) ;

    $Prix["Condensateurs"] = 3 ;

    $Prix["Transistors"] = 5 ;

    while( $Element = each($Prix))

    {

    echo "<BR/> <BR/>" ;

    echo "<font face='Arial' size='3' color='#005500'> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . $Element [ "key" ] ;

    echo "&nbsp; - &nbsp;" ;

    echo $Element[ "value" ] . "&nbsp; euros </font> </b>" ;

    }

    ?>

</BODY>

</HTML>

L'exécution de ce code produit le résultat montré à la figure 2.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Dans la première leçon, nous avons étudié les boucles while et l'instruction echo. Le fragment de code précédent met en oeuvre la fonction each(), que nous rencontrons ici pour la première fois. Cette fonction renvoie l'élément courant dans un tableau, et déplace le pointeur du tableau sur l'élément suivant. Dans ce code, la fonction each() est invoquée au sein d'une boucle while, de sorte à renvoyer successivement les différents éléments contenus dans le tableau. L'exécution de la boucle prend fin lorsque l'interpréteur PHP atteint la fin du tableau.

Dans ce code, la variable $Element est un tableau. A l'appel de la fonction each(), la variable $Element contient un tableau formé de quatre valeurs et des quatre clés qui leur sont associées et qui désignent les différentes positions dans le tableau. La position définie par key et 0 contient l'élément courant, tandis que la position définie par value et 1 contient la valeur de l'élément courant. Dans ce cas, nous avons choisi d'utiliser les positions désignées par des noms, plutôt que les positions désignées par des numéros. Au final toutefois, ces deux choix sont équivalents.

Il existe une manière plus élégante et plus commune d'obtenir ce résultat, en utilisant la fonction list() pour scinder le tableau en un ensemble de valeurs. Nous pouvons ainsi séparer deux des valeurs renvoyées par la fonction each(), de la manière suivante :

    list ($Produits, $Prix) = each ($Prix) ;

Dans cette ligne de code, la fonction each() est utilisée pour prendre l'élément courant du tableau $Prix, le renvoyer sous forme de tableau, et pour déplacer le pointeur du tableau sur l'élément suivant. La fonction list() est d'autre part mise en oeuvre pour transfomer les éléments 0 et 1 du tableau renvoyé par la fonction each() en deux nouvelles variables appelées $Produits et $Prix.

Nous pouvons ensuite accéder à tout le contenu du tableau $Prix, et l'afficher dans la fenêtre du navigateur au moyen des deux lignes de code qui suivent :

    while (list($Produits, $Prix) = each ($Prix))

    echo "$Produits - $Prix <BR>" ;

L'exécution de ces lignes de code produit le même résultat que celui montré à la figure 2. Ces lignes apparaissent toutefois plus facile à lire, parce que la fonction list() permet d'affecter des noms aux variables.

A propos de la fonction each(), notez que le tableau conserve la "mémoire" de l'élément courant. Si vous devez utiliser deux fois le même tableau dans un script, vous devez par conséquent replacer le pointeur du tableau sur le début du tableau, au moyen de la fonction reset.() Ainsi, pour afficher une deuxième fois les prix des articles, il nous faudrait exécuter les lignes de code suivantes :

    reset($Prix) ;

    while (list($Produits, $Prix) = each ($Prix))

    echo "$Produits - $Prix <BR>" ;

Tableaux multidimensionnels :

Les tableaux ne sont pas nécessairement de simples listes de clés et de valeurs. Chaque position au sein d'un tableau peut contenir un autre tableau. Le tableau est alors dit "multidimensionnel". Ce type de tableau peut être comparé à une matrice, ou une grille, avec une largeur et une hauteur défnies, ou avec un nombre défini de lignes et de colonnes.

Par exemple, nous pouvons avoir recours à un tableau multidimensionnel pour stocker plusieurs informations relatives à chaque article vendu par le biais du site de chez Jean-Pierre.

La figure 3 schématise un tableau bidimensionnel stockant les données concernant les articles de chez Jean-Pierre, dans lequel chaque ligne représente un article individuel, et chaque colonne représente un attribut (ou un type d'information) des articles.

Dans le contexte d'un scriptage PHP, le code qui suit pourrait être utilisé pour générer le tableau montré à la figure 3 :

    $Produits = array( array( "Resis", "Resistances", 2) ,

                       array( "Condos", "Condensateurs", 3) ,

                       array( "Transis", "Transistors", 5)) ;

Ces lignes font bien apparaître que le tableau $Produits créé se comporte de trois autres tableaux.

Souvenez-vous que pour accéder à un élément d'un tableau unidimensionnel, il faut spécifier le nom du tableau et la clé de l'élément. Dans un tableau bidimensionnel, l'accès s'effectue de manière comparable, si ce n'est qu'à chaque élément sont associées deux clés : une ligne et une colonne (la ligne la plus en haut est la ligne 0, tandis que la colonne la plus à gauche est la colonne 0).

Nous pourrions ainsi afficher le contenu du tableau bidimensionnel considéré ici en accédant dans l'ordre et manuellement à chaque élément, comme suit :

    echo "|" . $Produits[0][0] . "|" . $Produits[0][1] . "|" . $Produits[0][2] . "| <BR/>" ;

    echo "|" . $Produits[1][0] . "|" . $Produits[1][1] . "|" . $Produits[1][2] . "| <BR/>" ;

    echo "|" . $Produits[2][0] . "|" . $Produits[2][1] . "|" . $Produits[2][2] . "| <BR/>" ;

Nous pourrions obtenir le même résultat, en implémentant une boucle for au sein d'une autre boucle for, de la manière suivante :

    for ($ligne = 0; $ligne <3; $ligne++)

    {

        for ($colonne = 0; $colonne <3; $colonne++)

        {

          echo "|" . $Produits[$ligne][$colonne] ;

        }

          echo "| <BR/>" ;

    }

Chacune des deux variantes précédentes conduit au même affichage dans la fenêtre du browser ou navigateur Web, à savoir :

    | Resis | Resistances | 2 |

    | Condos | Condensateurs | 3 |

    | Transis | Transistors | 5 |

Pour visualiser l'aperçu sans boucle, en cliquant ici. [Exemple 3]. Pour visualiser l'aperçu avec boucle, en cliquant ici. [exemple 4]

La seule différence entre ces variantes est que la seconde est plus courte que la première, dans le cas de tableaux volumineux.

Au lieu de faire référence aux colonnes par des numéros, vous pouvez choisir d'utiliser des noms de colonnes comme c'est le cas de la figure 3. Pour cela, vous pouvez utiliser des tableaux associatifs. Pour stocker le même ensemble d'articles dans un tableau associatif dont les noms de colonnes seraient identiques à ceux de la figure 3, le code suivant pourrait être mis en oeuvre :

    $Produits = array( array( "Code" => "Resis" ,

                              "Description" => "Resistances" ,

                              "Prix" => 2

                            ),

                       array( "Code" => "Condos" ,

                              "Description" => "Condensateurs" ,

                              "Prix" => 3

                            ),

                       array( "Code" => "Transis" ,

                              "Description" => "Transistors" ,

                              "Prix" => 5

                            )

                        ) ;

Un tel tableau se révèle plus facile à manipuler lorsqu'il s'agit de retrouver une valeur individuelle. Il est en effet plus aisé de se souvenir que la description d'un article est stockée dans la colonne Description, que de se souvenir qu'elle est stockée dans la colonne 1. Avec les tableaux associatifs, il n'est pas nécessaire de mémoriser qu'une valeur est stockée à la position [x][y]. Les données peuvent y être facilement retrouvées en spécifiant les noms explicites des lignes et des colonnes.

L'usage de tableaux associatifs nous privent, en revanche de la possibilité d'utiliser une simple boucle for pour parcourir successivement les différentes colonnes du tableau. Le fragment de code qui suit permet d'afficher le contenu du tableau associatif $Produits considéré ici :

    for ($ligne = 0; $ligne <3; $ligne++)

    {

     echo "&nbsp;|&nbsp;" . $Produits[$ligne]["Code"] . "&nbsp;|&nbsp;" . $Produits[$ligne]["Description"] . "&nbsp;|&nbsp;" . $Produits[$ligne]["Prix"] . "&nbsp;|<BR/>" ;

    }

Une boucle for peut être mise en oeuvre pour parcourir le tableau "externe" $Produits indexé numériquement. Chaque ligne de ce tableau $Produit constitue un tableau associatif. Les fonctions each() et list() peuvent ensuite être insérées dans une boucle while pour parcourir les différents tableaux associatifs contenus dans $Produits. Voici le code ainsi formé d'une boucle while imbriquée dans une boucle for :

    for ($ligne = 0; $ligne <3; $ligne++)

    {

    while (list($key, $value) = each($Produits[$ligne]))

    {

    echo "|$value" ;

    }

    echo "|<BR/>" ;

    }

Pour visualiser l'aperçu de deux boucles for et while, en cliquant ici. [Exemple 5].

Vous pouvez créer des tableaux dont la dimension est bien supérieure à deux. Il suffit de créer un tableau dont les éléments sont constitués de tableaux, eux-mêmes constitués de tableaux, et ainsi de suite.

Un tableau tridimensionnel se caractérise par une largeur, une hauteur et une profondeur. Si vous préférez vous représenter un tableau bidimensionnel sous la forme d'une table composée de lignes et de colonnes, vous pouvez vous représenter un tableau tridimensionnel comme un empilement de telles tables. Chaque élément est alors référencé par sa couche, sa ligne et sa colonne.

Supposons que le site de chez Jean-Pierre classe ses articles en différentes catégories. Un tableau tridimensionnel pourrait être employé pour stocker cette information supplémentaire. La figure 4 montre la structure que pourrait avoir un tel tableau.

Dans le fragment de code qui suit, et qui définit le tableau schématisé de la figure 4, il apparaît clairement qu'un tableau tridimensionnel est un tableau contenant d'autres tableaux :

    $Categories = array( array( array( "TVC_Resis", "Resistances", 2 ),

                                array( "TVC_Condos", "Condensateurs", 3 ),

                                array( "TVC_Transis", "Transistors", 5 )

                              ),

                          array(array( "AUTO_Resis", "Resistances", 2 ),

                                array( "AUTO_Condos", "Condensateurs", 3 ),

                                array( "AUTO_Transis", "Transistors", 5 )

                              ),

                          array(array( "HI-FI_Resis", "Resistances", 2 ),

                                array( "HI-FI_Condos", "Condensateurs", 3 ),

                                array( "HI-FI_Transis", "Transistors", 5 )

                              )

                           ) ;

Etant donné que ce tableau ne comprend que des clés numériques, des boucles for imbriquées peuvent être utilisées pour afficher son contenu :

    for ($Couche = 0; $Couche < 3; $Couche++)

    {

       echo "<BR/> <font face='Arial' size='3' color='#800000'><b>&nbsp;&nbsp;&nbsp;&nbsp;Couche $Couche <BR/> <BR/>" ;

       for ($Ligne = 0; $Ligne < 3; $Ligne++)

       {

          for ($Colonne = 0; $Colonne < 3; $Colonne++)

             {

                echo "&nbsp;&nbsp;&nbsp;&nbsp;<font face='Arial' size='3' color='#005500'><b>&nbsp;|&nbsp;" . $Categories[$Couche][$Ligne][$Colonne] ;

             }

             echo "&nbsp;euros&nbsp;|&nbsp; </b> </font> </font> <BR/>" ;

       }

    }

Pour visualiser l'aperçu du tableau tridimensionnel, en cliquant ici. [Exemple 6].

Compte tenu de la manière dont sont créés les tableaux multidimensionnels, vous pouvez très bien générer des tableaux à quatre, cinq ou six dimensions. Le langage PHP n'impose en réalité aucune limite sur le nombre de dimensions d'un tableau. Toutefois, les constructions à plus de trois dimensions se révèlent difficiles à visualiser. Des tableaux à trois dimensions ou moins sont en général tout à fait suffisants pour traiter la plupart des problèmes et situations du monde réel.

Tri de tableaux :

Il apparaît souvent très utile de trier les données apparentées stockées dans les tableaux. Le tri du contenu d'un tableau unidimensionnel est très simple à implémenter en PHP.

Utilisation de la fonction sort() :

Les deux lignes de code qui suivent, conduisent au tri d'un tableau, par ordre alphabétique croissant :

    $Produits = array( "Resistances", "Condensateurs", "Transistors" ) ;

    sort($Produits) ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 7].

Dans l'ordre et après l'exécution de ce code, les éléments contenus dans le tableau sont à présent : Condensateurs, Résistances, Transistors.

Il est également possible de trier des valeurs par ordre numérique. Prenons le cas d'un tableau contenant les prix des articles vendus par Jean-Pierre. Le contenu de ce tableau pourrait être trié par ordre numérique croissant, au moyen des instructions suivantes :

    $Prix = array( 100, 70, 5 ) ;

    sort($Prix) ;

Dans l'ordre et après l'exécution de ce code, les prix seraient alors : 5, 70, 100. Il en va de soi, que nous montrerons pas un exemple car, c'est relativement facile du point de vue de programmation.

Notez que la fonction sort() est sensible à la casse (à l'utilisation de majuscules et minuscules). Les lettres majuscules ont systématiquement plus de poids que toute lettre minuscule. Ainsi, "A" est inférieure à "Z", mais "Z" est supérieure à "a".

Utilisation des fonctions asort() et ksort() pour trier des tableaux associatifs :

Si nous choisissons de stocker dans un tableau associatif les articles et les prix correspondants, nous devrons avoir recours à différents types de fonctions de tri pour obtenir que les clés et les valeurs correspondantes restent couplées lors du tri.

La première instruction qui suit crée un tableau associatif contenant les trois articles décrits précédemment, avec les prix correspondants, tandis que la deuxième ligne de code procède au tri de ce tableau par ordre de prix croissants :

    $Prix = array( "Resistances" => 2, "Condensateurs" => 3, "Transistors" => 5 ) ;

    asort($Prix) ;

La fonction asort() ordonne le contenu du tableau qui lui est fourni comme argument, d'après la valeur de chaque élément. Dans le tableau considéré ici, les valeurs sont les prix, tandis que les clés sont les descriptions textuelles. Pour trier le tableau non pas par prix, mais par description, c'est la fonction ksort() qui doit être employée. La fonction ksort() effectue un tri par clé et non pas par valeur. Le fragment de code qui suit aboutit à un tableau trié par ordre alphabétique des clés (Condensateurs, Résistances, Transistors).

    $Prix = array( "Resistances" => 2, "Condensateurs" => 3, "Transistors" => 5 ) ;

    ksort($Prix) ;

Tri dans l'ordre inverse :

Nous venons d'examiner les fonctions de tri sort(), asort() et ksort(), qui effectuent toutes trois des tris par ordre croissant. A chacune de ces fonctions correspondant une fonction de tri inverse, dont la fonctionnalité est identique si ce n'est qu'elle procède à un tri décroissant. Ces versions inverses des fonctions de tri sont respectivement rsort(), arsort() et krsort().

Les fonctions de tri inverse s'utilisent de la même manière que les fonctions de tri vues jusqu'ici. La fonction rsort() permet de trier par ordre décroissant un tableau unidimensionnel indexé numériquement. La fonction arsort trie par ordre décroissant le tableau associatif unidimensionnel qui est passé comme argument, à partir des valeurs des éléments. Quant à la fonction krsort(), elle trie un tableau associatif unidimensionnel par ordre décroissant, à partir des clés des éléments.

Tri de tableaux multidimentionnels :

Le tri d'un tableau à plus d'une dimension, ou par un ordre autre que l'ordre alphabétique ou numérique, se révèle plus compliqué. L'interpréteur PHP sait comparer deux nombres ou deux chaînes de caractères. Mais dans un tableau multidimensionnel, chaque élément est lui-même un tableau. L'interpréteur PHP ne connaît pas d'emblée les critères à retenir pour comparer deux tableaux. Par conséquent, vous devez créer une méthode pour opérer cette comparaison. Le plus souvent, la comparaison de mots ou de nombres est triviale. Par contre, pour des objets complexes, le tri peut se révéler problèmatique.

Tris définis par l'utilisateur :

Soit le tableau déjà considéré précédemment, et dont la définition est la suivante :

    $Produits = array( array( "Resis", "Resistances", 2) ,

                       array( "Condos", "Condensateurs", 3) ,

                       array( "Transis", "Transistors", 5)) ;

Ce tableau contient trois articles vendus par le site de chez Jean-Pierre, avec un code, une description et un prix par article.

A quel résultat aboutira le tri de ce tableau ? Deux types d'ordre au moins pourraient ici être utiles : un tri des articles par ordre alphabétique des descriptions, ou par ordre numérique des prix. Chacun de ces tris peut être implémenté, en utilisant la fonction usort() et en indiquant à l'interpréteur PHP le critère sur lequel la comparaison doit s'effectuer. Pour cela, nous allons devoir écrire notre propre fonction de comparaison.

Le fragment de code donné ci-dessous conduit au tri du tableau considéré ici par ordre alphabétique des descriptions, c'est-à-dire par rapport à la deuxième colonne du tableau :

    function compare($x, $y)

       {

          if ($x[1] == $y[1] )

             return 0 ;

          elseif ($x[1] < $y[1])

             return -1 ;

          else

             return 1 ;

       }

    usort($Produits, "compare") ;

Pour de plus amples informations et de compréhension, nous indiquons le programme complet du tableau bidimensionnel comme suit, afin de bien utiliser la fonction usor() :

<HTML>

<HEAD>

<TITLE> Tris D&eacute;finis par l'Utilisateur </TITLE>

</HEAD>

<BODY>

<BR/> <BR/>

<H2> Tableau Bidimensionnel - Utilisation avec la fonction "usort()" uniquement r&eacute;serv&eacute; pour les fonctions cr&eacute;&eacute;es par l'utilisateur donc, tri du tableau par ordre alphab&eacute;tique croissant des composants &eacute;lectroniques, concernant cet exemple. </H2>

<?php

    function compare($x, $y)

       {

          if ($x[1] == $y[1] )

             return 0 ;

          elseif ($x[1] < $y[1])

             return -1 ;

          else

             return 1 ;

       }

    echo "<BR/> <BR/>" ;

    $Produits = array( array( "Resis", "Resistances", 2) ,

                       array( "Condos", "Condensateurs", 3) ,

                       array( "Transis", "Transistors", 5)) ;

    usort($Produits, "compare") ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;<font face='Arial' size='3' color='#005500'> <b>" . $Produits[0][0] . "&nbsp;|&nbsp;" . $Produits[0][1] . "&nbsp;|&nbsp;" . $Produits[0][2] . "&nbsp;euros | <BR/>" ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;" . $Produits[1][0] . "&nbsp;|&nbsp;" . $Produits[1][1] . "&nbsp;|&nbsp;" . $Produits[1][2] . "&nbsp;euros | <BR/>" ;

    echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;" . $Produits[2][0] . "&nbsp;|&nbsp;" . $Produits[2][1] . "&nbsp;|&nbsp;" . $Produits[2][2] . "&nbsp;euros | </b> </font> <BR/>" ;

?>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 8].

Jusqu'ici dans cette leçon, nous avons mis en oeuvre diverses fonctions prédéfinies dans le langage PHP. Pour trier notre tableau, nous avons nous-même défini une fonction dans le code précédent. L'écriture de fonctions personnalisées seront traitées, en détail dans les prochaines leçons, mais, pour l'heure, en voici une briève explication.

La définition d'une fonction en PHP requiert le mot clé function. Pour définir une fonction personnalisée, vous devez attribuer un nom à votre fonction. Choisissez des noms explicites. Dans le cas considéré ici par exemple, nous avons choisi de nommer notre fonction compare(). Nombre de fonctions prennent des paramètres ou des arguments. Notre fonction compare() en prend deux : un argument appelé x, et un argument appelé y. Cette fonction sert à comparer les deux valeurs qui lui sont passées comme argument.

Pour cet exemple, les paramètres x et y contiendront deux des tableaux stockés dans le tableau principal, et qui représentent chacun un article différent. Pour accéder à la Description du tableau x, nous devons taper $x[1]. En effet, la Description est le deuxième élément dans chacun des "sous-tableaux", et la numérotation commence à zéro. Les variables tableaux $x[1] et $y[1] sont utilisés pour comparer les Descriptions stockées dans les tableaux passés comme arguments à la fonction compare().

Lorsque l'exécution d'une fonction s'achève, celle-ci peut retourner une réponse au code qui l'a invoquée. On dit alors que la fonction renvoie une valeur. Pour qu'une fonction renvoie une valeur, vous devez y inclure le mot clé return. Par exemple, la ligne de code return 1 ; renvoie la valeur 1 au code qui a appelé la fonction.

Pour que la valeur renvoyée par compare() puisse être utilisée par usort(), la fonction compare() doit comparer x et y. La fonction doit renvoyer la valeur 0 si x est égal à y, un nombre négatif si x est inférieur à y, et un nombre positif si x est supérieur à y. Notre fonction compare renvoie ainsi 0, 1, ou - 1 selon les valeurs x et y qui lui sont fournies.

La dernière ligne du code (couleur rouge foncée) précédent invoque la fonction usort(), prédéfinie dans PHP. Le nom du tableau à trier doit être spécifié dans l'appel de la fonction usort(), ainsi que le nom d'une fonction de comparaison personnalisée, en l'occurrence compare().

Pour trier notre tableau sur d'autres critères, il suffit d'ajuster la définition de notre fonction de comparaison. Par exemple, pour obtenir le tri du tableau par prix, la comparaison doit porter sur la troisième colonne des tableaux. La définition de la fonction compare() devrait alors être la suivante :

    function compare($x, $y)

       {

          if ($x[2] == $y[2] )

             return 0 ;

          elseif ($x[2] < $y[2])

             return -1 ;

          else

             return 1 ;

       }

    usort($Produits, "compare") ;

L'exécution de l'instruction ($Produits, "compare") produit le tri du tableau par ordre de prix croissants.

Le préfixe "u" de la fonction usort() est l'abréviation de user (utilisateur). En effet, cette fonction requiert la spécification d'une fonction de comparaison définie par l'utilisateur. De la même manière, les versions uasort() et uksort() des fonctions asort() et ksort() nécessitent également qu'une fonction de comparaison définie par l'utilisateur leur soit passée comme argument.

La fonction uasort() fait pendant à la fonction asort(), et s'utilise pour trier un tableau associatif par valeurs. Invoquez asort() lorsque les valeurs sont de simples nombres ou du texte. Si les valeurs sont des objets plus compliqués, comme des tableaux, définissez une fonction de comparaison, et utilisez la fonction prédéfinie uasort().

La fonction uksort() fait pendant à la fonction ksort(), et s'utilise pour trier un tableau associatif par clés. Invoquez ksort() lorsque les clés sont de simples nombres ou du texte. Si les clés sont des objets plus compliqués, comme des tableaux, définissez une fonction de comparaison, et utilisez la fonction prédéfinie uksort().

Tris définis par l'utilisateur, dans l'ordre inverse :

Chacune des fonctions sort(), asort() et ksort() a son équivalent, comprenant un "r" (reverse) dans le nom de la fonction, et qui produit un tri dans l'ordre inverse. Par contre, dans le cas des tris définis par l'utilisateur, il n'existe pas directement de variante effectuant le tri inverse. Il est néanmoins possible de trier un tableau multidimensionnel dans l'ordre inverse, en fournissant une fonction de comparaison qui renvoie les valeurs opposées. Ainsi, pour obtenir un tri dans l'ordre inverse, il suffit que la fonction de comparaison renvoie la valeur 1 lorsque x est inféreur à y et -1 lorsque x est supérieur à y. Par exemple :

    function ReverseCompare($x, $y)

       {

          if ($x[2] == $y[2] )

             return 0 ;

          elseif ($x[2] < $y[2])

             return 1 ;

          else

             return -1 ;

       }

    usort($Produits, "ReverseCompare") ;

Pour visualiser l'aperçu, en cliquant ici. [Exemple 9].

L'invocation de la fonction usort ($Produits, "ReverseCompare") à la suite du code précédent produirait un tableau trié par ordre de prix décroissants.

Pour l'instant, nous terminons ce premier chapitre et nous verrons dans le prochain, la suite de cette leçon de certaines fonctions intéressantes, (shuffle()) et le chargement de tableau à partir de fichiers, etc. ...


Créer votre Base de Données Web

Conception de votre base de données Web (2ème partie) :

Créer votre base de données :

Dans cette leçon, nous reprendrons l'exemple de la librairie virtuelle de chez Jean-Pierre présentée à la leçon précédente. Voici le schéma de l'application de chez Jean-Pierre :

les_clients(client_ID, nom, adresse, ville)

les_commandes(commande_ID, client_ID, montant, date)

les_livres(ISBN, auteur, titre, prix)

les_articles_commandes(commande_ID, ISBN, quantitee)

les_commentaires_livres(ISBN, commentaires)

N'oubliez pas que les clés primaires sont soulignées en continu, et que les clés externes sont soulignées en pointillés.

Pour pouvoir continuer cette leçon, vous devez avoir accès à MySQL. Cela signifie normalement que :

  1. Vous avez effectué l'installation de base de MySQL sur votre serveur Web. Pour cela, il faut normalement :

  • Installer les fichiers de EasyPHP, en cliquant ici et selon votre système d'exploitation.

  • Configurer votre EasyPHP ou autres serveurs, selon votre choix.

  • Exécuter mysql_install_db, si nécessaire et selon les serveurs vous concernant.

  • Définir le mot de passe root mais, ce n'est pas une obligation, uniquement pour votre sécurité.

  • Supprimer le cas échéant l'utilisateur anonymous.

  • Et enfin, démarrer le serveur MySQL et le configurer pour qu'il soit exécuté automatiquement.

Si vous avez bien fait tout cela, vous pouvez commencer ou continuer à lire cette leçon en toute tranquillité. Dans le cas contraire, recommencez l'installation de votre EasyPHP, afin que vous puissiez faire nos exemples.

Si, à n'importe quel moment dans ce deuxième chapitre, vous avez rencontré des problèmes, il se peut que la configuration de votre système MySQL soit en cause. Dans ce cas, vérifiez à nouveau pour vous assurer que votre configuration est correcte.

2. Vous devez avoir accès à MySQL sur un ordinateur que vous n'administrez pas, comme un service d'hébergement Web, un ordinateur de votre bureau, etc.

Dans ce cas, pour que vous puissiez utiliser les exemples ou créer votre propre base de données, votre administrateur doit configurer un utilisateur et une base de données, et vous fournir le nom d'utilisateur, le mot de passe, et le nom de la base de données qu'il a choisi.

Tous les exemples de cette leçon et les suivantes, ont été développés et testés à partir de la version 4 de MySQL et ultérieure. Certaines versions antérieures de MySQL possèdent moins de fonctionnalités. Il convient donc d'installer la version stable la plus récente lorsque vous configurez votre système. Vous pouvez changer la dernière version sur le site de MySQL, en cliquant ici

Création des bases de données et des utilisateurs :

Le système de base de données de MySQL peut supporter différentes bases de données. Généralement, il existe une base de données par application. Dans notre exemple de la librairie de chez Jean-Pierre, la base de données sera appelée books (en minuscule). ce qui signifie livres.

Nous mettons à votre disposition une capture d'une base de données pour celles ou pour ceux qui ne connaissent pas cette dernière, elle sera expliquée au fur et à mesure dans nos leçons quand cela sera nécessaire.

Création de la base de données :

Il s'agit de la partie la plus simple. Sur la ligne de commande de MySQL, saisissez la commande suivante :

    create database dbname ;

Il convient de substituer le nom de la base de données que vous souhaitez créer à dbname. Par exemple, pour chez Jean-Pierre, vous pouvez créer une base de données appelée dbname.

C'est tout. Vous devriez obtenir une réponse comme celle-ci :

    Query OK, 1 row affected (0.06 seconde) ce qui signifie : Requête OK, 1 ligne affectée en 0.06 seconde.

Cette réponse signifie que tout s'est bien passé. Si vous obtenez une autre réponse, assurez-vous que vous n'avez pas oublié de saisir le point-vigule à la fin de la ligne. Un point-virgule indique à MySQL que vous avez terminé de saisir votre commande, et qu'il doit l'exécuter.

Utilisateurs et privilèges :

Un système MySQL peut compter plusieurs utilisateurs. L'utilisateur root doit généralement servir uniquement pour l'administration du système, à cause de certains problèmes de sécurité. Pour chaque utilisateur qui doit avoir accès au système, vous devez définir un compte et un mot de passe. Ces derniers ne correspondent pas forcément aux noms d'utilisateurs ou aux mots de passe existant en dehors de MySQL (par exemple, les noms d'utilisateur et les mots de passe Unix ou NT). Ce principe est également valable pour le compte root. Il est généralement conseillé de choisir un mot de passe différent pour les comptes du système et pour les comptes de MySQL, et en particulier pour le compte root. Ce qui signifie root = racine.

Il n'est pas obligatoire de créer des mots de passe pour les utilisateurs, mais nous vous recommandons fortement de choisir un mot de passe pour tous les utilisateurs que vous créez.

Dans le cadre de la configuration d'une base de données Web, il est généralement intéressant de créer au moins un utilisateur par application Web.

Vous pouvez vous demander : "Et pourquoi cela ?" La réponse fait intervenir la notion de privilèges.

Introduction au système de privilèges de MySQL :

L'une des caractéristiques les plus intéressantes de MySQL est qu'il supporte un système évolué de privilèges.

Un "privilège" est le droit d'effectuer une action particulière sur un objet spécifique, en association avec un utilisateur particulier. Ce concept ressemble énormément aux droits d'accès des fichiers.

Lorsque vous créez un utilisateur dans MySQL, vous lui accordez un ensemble de privilèges pour spécifier ce qu'il peut faire et ne peut pas faire dans le système.

Principe de privilèges minimaux :

Ce principe peut être utilisé pour améliorer la sécurité de n'importe quel système informatique. Il s'agit d'un principe à la fois très simple et très important, que l'on oublie un peu trop souvent. Il peut être résumé de la manière suivante :

  • Un utilisateur (ou un processus) doit posséder le niveau de privilège le plus bas possible pour pouvoir effectuer correctement sa tâche.

Ce principe s'applique également à MySQL. Par exemple, pour exécuter des requêtes à partir du Web, un utilisateur n'a pas besoin de posséder tous les privilèges auxquels root a accès. Il convient par conséquent de créer un autre utilisateur qui possède uniquement les privilèges nécessaires pour accéder à la base de données que nous venons de créer (dbname).

Configuration des utilisateurs - la commande GRANT :

Les commandes GRANT et REVOKE sont utilisées pour fournir ou pour retirer des droits d'accès aux utilisateurs de MySQL, selon quatre niveaux de privilèges, qui sont les suivants :

global ;

database ;

table ;

column ;

Nous allons voir à quoi correspond chacun de ces niveaux.

La commande GRANT est utilisée pour créer des utilisateurs et pour leur fournir des privilèges. Voici le format général de la commande GRANT :

    GRANT privileges [columns]

    ON item

    TO user_name [IDENTIFIED BY 'password']

    [WITH GRANT OPTION]

Les clauses entre crochets sont optionnelles. Dans cette syntaxe, il faut modifier plusieurs mots clés.

Le premier, privileges, est une liste de privilèges séparés par des virgules. Ces privilèges doivent être choisis dans une liste prédéfinie de MySQL, que nous verrons dans la prochaine section de cette leçon.

Le mot clé columns est optionnel. Vous pouvez l'utiliser pour spécifier les privilèges de chaque colonne. Il peut correspondre au nom d'une seule colonne, ou à une liste de noms de colonnes séparés par des virgules.

Le mot clé item correspond à la base de données ou au tableau auquel les privilèges doivent être appliqués.

Vous pouvez modifier les privilèges de toutes les bases de données en spécifiant *.* à la place de item. C'est ce que l'on appelle une modification des privilèges "globaux". Vous pouvez aussi spécifier * si vous n'utilisez aucune base de données particulière.

Plus fréquemment, vous pouvez spécifier tous les tableaux d'une base de données grâce à dbname .*. que nous avons créé, un tableau particulier grâce à dbname.tablename, ou une colonne particulière avec dbname.tablename et un argument spécifique à la place de columns. Ces trois approches représentent les trois autres niveaux de privilèges disponibles : database, table et column, respectivement. Si vous utilisez une base de données spécifique lorsque vous exécutez cette commande, tablename sera interprété comme un tableau dans la base de données actuelle.

Le mot clé user_name doit correspondre au nom de l'utilisateur sous lequel vous souhaitez vous logger dans MySQL. N'oubliez pas que ce nom ne doit pas forcément correspondre à votre nom d'utilisateur sur votre système d'exploitation. Dans MySQL, user_name peut également correspondre à un nom d'hôte. Vous pouvez utiliser cette particularité pour différencier par exemple, Laura (qui sera interprété comme laura@localhost), et laura@autre-part.com. Cette particularité et très intéressante puisqu'il arrive souvent que des utilisateurs de différents domaines aient le même nom en local. Cette caractéristique améliore en outre la sécurité du système, puisque vous pouvez spécifier l'endroit à partir duquel les utilisateurs se connectent, et même les tableaux et les bases de données auxquels ils ont accès à partir d'un emplacement particulier.

Le mot clé password doit correspondre au mot de passe associé à l'utilisateur spécifié. Les règles générales pour choisir les mots de passe doivent toujours être respectées. Nous reviendrons un peu plus loin sur les problèmes de sécurité, mais, d'une manière générale, un mot de passe ne doit pas pouvoir être deviné facilement. Cela signifie qu'un mot de passe ne doit figurer dans aucun dictionnaire, et doit être différent du nom de l'utilisateur. Idéalement, il doit contenir des lettres majuscules, des lettres minuscules, et des symboles.

L'option WITH GRANT OPTION, lorsqu'elle est spécifiée, permet à l'utilisateur de sélectionner et de définir ses propres privilèges.

Les privilèges sont enregistrés dans quatre tableaux systèmes, dans la base de données appelé mysql. Ces quatre tableaux sont appelés mysql.user, mysql.db, mysql.tables_priv et mysql.columns_priv. Ils correspondent directement aux niveaux de privilèges que nous avons déjà mentionnés. Si vous ne souhaitez pas passer par GRANT, vous pouvez modifier directement ces tableaux. Nous y reviendrons, en détail dans les prochaines leçons qui seront tirées et extraites de nos catalogues concernant les paramètrages des privilèges.

Types et niveaux de privilèges :

Il existe trois principaux types de privilèges dans MySQL : les privilèges des utilisateurs classiques, les privilèges des administrateurs et quelques privilèges particuliers.

N'importe quel utilisateur peut obtenir ces privilèges, mais il est généralement plus intéressant d'affecter les privilèges des administrateurs uniquement aux administrateurs, selon le principe des privilèges minimaux.

Les privilèges doivent être accordés aux utilisateurs uniquement pour les bases de données et les tableaux qu'ils devront utiliser. La base de données mysql ne doit être accessible que pour les administrateurs. En effet, il s'agit de l'endroit où tous les utilisateurs, tous les mots de passe, etc. sont enregistrés (nous reviendrons sur cette base de données dans les prochaines leçons suivantes).

Les privilèges des utilisateurs classiques sont directement associés à des types spécifiques de commandes SQL, et définissent les droits d'exécution de ces commandes par les utilisateurs. Nous reviendrons sur ces commandes SQL au chapitre suivant. Pour l'instant, nous avons fourni une description conceptuelle de ces commandes. Ces privilèges sont présentés dans le tableau 1 ci-dessous. La deuxième colonne spécifie les objets auxquels chaque privilège peut être appliqué.

Tableau 1. - Privilèges des utilisateurs :
Privilèges | Applicable à | Description
SELECT | Tableaux, colonnes | Permet aux utilisateurs de sélectionner des lignes (des enregistrements) dans des tableaux.
INSERT | Tableaux, colonnes | Permet aux utilisateurs d'insérer de nouvelles lignes dans des tableaux.
UPDATE | Tableaux, colonnes | Permet aux utilisateurs de modifier les valeurs existantes dans les lignes des tableaux.
DELETE | Tableaux | Permet aux utilisateurs de supprimer des lignes existantes dans des tableaux.
INDEX | Tableaux | Permet aux utilisateurs de créer et de supprimer des indices dans des tableaux particuliers.
ALTER | Tableaux | Permet aux utilisateurs de modifier la structure de tableaux existants, par exemple, en ajoutant des colonnes, en renommant des colonnes ou des tableaux, ou en modifiant le type des données de certaines colonnes.
CREATE | Base de données, tableaux | Permet aux utilisateurs de créer de nouvelles bases de données ou de nouveaux tableaux. Si un tableau ou une base de données particuliers sont spécifiés dans la commande GRANT, ce tableau ou cette base de données ne peuvent être créés que grâce au privilège CREATE, ce qui signifie qu'il faut utiliser au préalable DROP.
DROP | Base de données, tableaux | Permet aux utilisateurs de supprimer des bases de données ou des tableaux.

La plupart des privilèges des utilisateurs classiques sont relativement inoffensifs, en terme de sécurité. Le privilège ALTER peut être utilisé pour contourner les privilèges systèmes, en renommant des tableaux, mais, il est souvent très important pour les utilisateurs. La sécurité est toujours un compromis entre la sûreté et la simplicité d'utilisation. Vous devez donc prendre vos propres décisions quant à ALTER, Mais il faut savoir que ce privilège est souvent accordé aux utilisateurs classiques.

En plus des privilèges présentés dans le Tableau 1, il existe un privilège appelé REFERENCES, qui n'est pas encore utilisé, et un privilège GRANT, qui est accordé avec WITH GRANT OPTION plutôt qu'avec la liste privileges.

Le Tableau 2 présente les privilèges réservés aux administrateurs.

Tableau 2. - Privilèges des administrateurs :
Privilèges | Description
RELOAD | Permet à un administrateur de recharger les tableaux de privilèges, et de réinitialiser les privilèges, les hôtes, les journaux et les tableaux.
SHUTDOWN | Permet à un administrateur d'arrêter le serveur MySQL.
PROCESS | Permet à un administrateur de visualiser les processus du serveur et de les tuer.
FILE | Permet d'échanger des données entre les tableaux et des fichiers.

Il est possible de fournir ces privilèges à des utilisateurs classiques, mais, dans ce cas, il faut être très prudent. En principe, les utilisateurs n'ont pas besoin d'utiliser les privilèges RELOAD, SHUTDOWN ou PROCESS.

Le privilège FILE est un peu différent. Il est intéressant pour les utilisateurs puisqu'il permet de charger des données à partir de simples fichiers, ce qui peut leur faire gagner beaucoup de temps, en leur évitant d'avoir à saisir leurs données dans leurs bases de données. Cependant, le mécanisme de chargement de fichiers peut être utilisé pour charger n'importe quel fichier visible par le serveur MySQL, y compris des bases de données appartenant à d'autres utilisateurs, et éventuellement des fichiers de mot de passe. Ce privilège ne doit donc être accordé qu'avec beaucoup de précautions, et vous pouvez préférer charger les données des utilisateurs à leur place.

Il existe également deux privilèges particuliers, qui sont présentés dans le Tableau 3.

Tableau 3. - Privilèges particuliers :
Privilèges | Description
ALL | Accorde tous les privilèges présentés dans les Tableaux 1 et 2. Vous pouvez également écrire ALL PRIVILEGES à la place de ALL.
USAGE | N'accorde aucun privilège. Cela permet de créer un utilisateur et de ne l'autoriser qu'à ce logger, sans pouvoir faire autre chose. Généralement, il s'agit simplement d'une première étape utilisée avant d'ajouter d'autres privilèges.

La commande REVOKE :

L'inverse de GRANT est REVOKE. Cette commande est utilisée pour supprimer les privilèges des utilisateurs. Sa syntaxe ressemble beaucoup à celle de GRANT :

    REVOKE privileges [(columns)]

    ON item

    FROM user_name

Si vous avez spécifié la clause WITH GRANT OPTION, vous pouvez la supprimer ainsi :

    REVOKE GRANT OPTION

    ON item

    FROM user_name

Exemples d'utilisation de GRANT et de REVOKE :

Pour configurer le compte d'un administrateur, vous pouvez saisir la commande suivante :

    GRANT ALL

    ON *

    TO jennifer identified by '123456'

    WITH GRANT OPTION ;

Voici un aperçu d'une capture :

Cette commande fournit tous les privilèges sur toutes les bases de données à une utilisatrice appelée Jennifer, avec le mot de passe 123456, et elle permet de transmettre ces privilèges.

Nous mettons un aperçu d'une capture des privilèges concernant l'utilisatrice Jennifer afin que vous puissiez vous rendre compte, à noter, vous pouvez cocher ou décocher les cases de la base de données d'un utilisateur selon les privilèges que vous attribuez.

Il est fort possible que vous ne souhaitez pas réellement définir cette utilisatrice dans votre système, c'est pourquoi que vous pouvez la supprimer immédiatement :

    REVOKE ALL

    ON *

    FROM jennifer ;

Nous mettons également une capture concernant la suppression des privilèges de Jennifer.

Voyons maintenant comment configurer le compte d'un utilisateur classique, sans aucun privilège :

    GRANT USAGE

    ON books . *

    TO jennifer identified by 'magique123' ;

Après avoir discuté un peu avec Jennifer, et après avoir appris ce qu'elle souhaite réellement faire, nous pouvons lui fournir les privilèges correspondants :

    GRANT select, insert, update, delete, index, alter, create, drop

    ON books . *

    TO jennifer ;

Vous remarquerez que nous n'avons pas besoin de spécifier le mot de passe de Jennifer pour effectuer cette opération.

Si l'on se rend compte que Jennifer abuse de ses privilèges, on peut choisir de les réduire :

    REVOKE alter, create, drop

    ON books . *

    FROM jennifer ;

Et pour terminer, lorsqu'elle n'a plus besoin d'utiliser la base de données, on peut supprimer tous ces droits :

    REVOKE ALL

    ON books . *

    FROM jennifer ;

Voici un aperçu ci-après :

Nous terminons ainsi ce deuxième chapitre (2ème partie de cette leçon) et nous verrons dans le prochain, comment Configurer un Utilisateur pour le Web, Utiliser la bonne base de données, sans oublier la Création des Tableaux de la Base de Données.


Implémentation de l'authentification des users

Authentifier les Utilisateurs et personnaliser le site (2ème partie) :

Implémentation de base du site :

La première page que nous allons construire sera appelée login.php ou connexion.php, puisqu'elle permet aux utilisateurs de se logger sur le système via connexion.php ou login.php. Les codes de cette page sont identiques est présenté dans le Listing 3.

Listing 3. - connexion.php ou login.php - La page d'accueil de PHP "Bookmarks" :

Nous devons reconnaître que le code n'est pas très simple, puisqu'il se contente essentiellement d'appeler certaines fonctions que vous devriez comprendre pour cette application, si vous aviez bien suivi nos leçons précédentes. Mais cependant, nous reviendrons sur les détails d'implémentation de ces fonctions, mais néanmoins, vous devez faire l'effort de comprendre le fonctionnement de connexion.php ou du login.php. Nous pouvons constater que nous incluons un fichier (contenant certaines fonctions), et que nous appelons certaines fonctions pour créer un en-tête HTML, afficher un contenu, et créer un code HTML de bas de page que nous verrons pas la suite de nos leçons.

La sortie de ce script est présentée à la figure 4.

Toutes les fonctions du système se trouvent dans le fichier bookmark_fns.php présenté dans le Listing 4.

Listing 4. - bookmark_fns.php - Le fichier à inclure contenant les fonctions de l'application de PHP "Bookmarks" :

Comme vous pouvez le constater, ce fichier se contente d'inclure cinq autres fichiers que nous utiliserons dans cette application. Nous avons choisi cette structure puisque ces fonctions peuvent être classées en cinq groupes logiques. Certains de ces groupes pourront être réutilisés dans d'autres projets, c'est pourquoi que nous avons choisi de placer chaque groupe de fonctions dans un fichier séparé, que nous pourrons réutiliser lorsque nous en aurons besoin. Nous les avons réunis dans le fichier bookmark_fns.php, puisque la plupart de ces fonctions sont utilisées dans la plupart de nos scripts. Il est plus simple d'inclure un seul fichier dans chaque script que d'inclure uniquement les fichiers nécessaires.

Vous remarquerez que la fonction require_once() n'existe qu'à partir de la version 4 de PHP. Si vous vous servez d'une version antérieure, vous devez utiliser require_once() ou include_once() pour vous assurer que ce fichier n'est pas chargé plusieurs fois.

Dans ce cas particulier, nous utilisons des fonctions du fichier output_fns.php. Il s'agit de fonctions relativement simples, qui génèrent du code HTML brut. Ce fichier inclut les quatre fonctions dont nous nous sommes servi, c'est-à-dire do_html_header(), display_site_info(), display_login_form et do_html_footer(), entre autres.

Nous n'étudierons pas toutes ces fonctions en détail, mais nous allons cependant nous intéresser à l'une d'entre elles, à titre d'exemple. Le code de do_html_header() se trouve dans le Listing 5. A noter que nous mettrons les quatre autres fonctions et bien plus encore, se trouvant dans le même fichier output_fns.php.

Listing 5. - La fonction do_html_header() de output_fns.php - Cette fonction renvoie l'en-tête standard qui apparaîtra sur chaque page de l'application :

Comme vous pouvez le constater, cette fonction se contente d'ajouter le titre et l'en-tête appropriés dans la page. Les autres fonctions dont nous nous sommes servi dans login.php ou connexion.php sont similaires. La fonction display_site_info() ajoute un texte général sur le site. display_login_form() affiche le formulaire de la figure 4 ci-dessus, et do_html_footer() ajoute le code HTML de bas de page standard.

En examinant la figure 4, vous pouvez constater que celle-ci contient deux options : l'utilisateur peut s'enregistrer, ouvrir une session s'il s'est déjà enregistré ou réinitialiser son mot de passe s'il l'a oublié via un autre module que l'on verra au cours de nos leçons. Pour implémenter ces modules, nous devons passer à la section suivante, consacrée à l'authentification des utilisateurs.

Implémentation de l'authentification des utilisateurs :

Le module d'authentification des utilisateurs contient quatre éléments principaux : l'enregistrement des utilisateurs, l'ouverture et la fermeture des sessions, la modification des mots de passe, et leur réinitialisation. Nous allons maintenant nous intéresser à chacun de ces éléments.

Enregistrement :

Pour enregistrer un utilisateur, celui-ci doit saisir dans un formulaire ses détails personnels, et nous devons l'ajouter dans la base de données.

Lorsqu'un utilisateur clique sur le lien "Veuillez vous inscrire à votre espace Membre" de la page index.php, il arrive sur un formulaire d'enregistrement créé par sign_up.php. Ce script est présenté dans le Listing 6.

Listing 6. - Le fichier sign_up.php - Ce formulaire et script permet aux utilisateurs de s'enregistrer sur le site de PHP Bookmarks :

Une fois encore, vous pouvez constater que le script de cette page n'est pas très simple, mais, il n'en est rien. En fait, il suffit de faire sa structure complète sur une feuille de papier et de bien réfléchir. Par ailleurs, elle se contente de tester un certain nombre de conditions. La figure 5 représente le résultat de ce script.

Il s'agit du premier script un peu complexe de cette application.

Ce script commence par inclure les fichiers de fonctions de l'application, avant d'ouvrir une session. Lorsque l'utilisateur est enregistré, nous nous servons de son nom d'utilisateur comme variable de session, comme nous l'avons fait dans une des leçons précédentes.

Ensuite, nous validons des données d'entrée saisies par l'utilisateur. Nous devons tester un certain nombre de conditions :

  • Vérifier que le formulaire est rempli correctement. Pour cela, nous appelons la fonction isset() :

if(isset($_POST['username'], $_POST['password'], $_POST['passverif'], $_POST['email'], $_POST['avatar']) and $_POST['username']!='')

  • Vérifier également qu'il n'y a pas d'espaces blanc avant et après les mots, concernant la base de données qui est très importante à nos yeux :

$username = trim("$username") ; // Supprime les espaces (ou d'autres caractères) en début et fin de chaîne

$password = trim("$password") ;

$email = trim("$email") ;

$avatar = trim("$avatar");

  • Vérifier que l'adresse E-Mail fournie est valide à l'aide de la fonction preg_match() :

if(preg_match('#^(([a-z0-9!\#$%&\\\'*+/=?^_`{|}~-]+\.?)*[a-z0-9!\#$%&\\\'*+/=?^_`{|}~-]+)@(([a-z0-9-_]+\.?)*[a-z0-9-_]+)\.[a-z]{2,}$#i',$_POST['email']))

Concernant les messages d'erreurs ou d'avertissement pour les utilisateurs, voir le Listing 6 du fichier sign_up.php.

  • Vérifier que les deux mots de passe saisis par l'utilisateur sont les mêmes :

if($_POST['password'] == $_POST['passverif'])

Idem pour les messages d'erreurs, voir le Listing 6.

  • Vérifier que la longueur du mot de passe est appropriée :

if(strlen($_POST['password']) >= 6)

Idem pour les messages d'erreurs, voir le Listing 6.

  • Vérifier également qu'il n'y a pas d'autres utilisateurs inscris avec le même Nom ou avec le même Pseudo :

$dn = mysql_num_rows(mysql_query('SELECT id FROM membre_utilisateurs WHERE Nom_Utilisateur="' . $username.'"'));

if($dn==0)

Idem pour les messages d'erreurs, voir le Listing 6.

Dans cette application, le mot de passe doit contenir au moins six caractères pour qu'il soit suffisamment difficile à deviner, et moins de 15 caractères via l'instruction maxlength = "15" pour les champs, pour tenir dans notre base de données.

Après avoir validé les données d'entrée, nous pouvons enregistrer l'utilisateur. Si vous revenez au Listing 6, vous verrez que nous le faisons de la manière suivante :

<DIV CLASS = "message">Vous avez bien été inscrit. Vous pouvez dorénavant vous connecter.<BR /> <BR />

<a href="connexion.php">Se connecter</a></div>

Comme vous pouvez le constater, nous appelons la variable $message. Si cette variable ne renvoie aucune erreur, nous enregistrons le nom d'utilisateur dans une variable de session, et nous affichons un lien vers la page principale des membres. C'est ce que montre la figure 6.

if(isset($message)) //On affiche un message s'il y a lieu

{

echo '<DIV CLASS = "message">'.$message.'</DIV>' ;

}

La variable $dn vérifie s'il n'y a pas déjà un utilisateur inscrit dans notre base de données.

//On vérifie s'il n'y a pas déjà un utilisateur inscrit avec le Pseudo choisi

$dn = mysql_num_rows(mysql_query('SELECT id FROM membre_utilisateurs WHERE Nom_Utilisateur="' . $username.'"'));

if($dn == 0)

{

//On récupère le nombre d'utilisateurs pour donner un identifiant à l'utilisateur actuel

$dn2 = mysql_num_rows(mysql_query('SELECT id FROM membre_utilisateurs'));

$id = $dn2 + 1;

//On enregistre les informations dans la base de donnée

if(mysql_query('INSERT INTO membre_utilisateurs(id, Nom_Utilisateur, Mot_de_Passe, E_Mail, Avatar, Signature_Date) values ('.$id.', "'.$username.'", "'.$password.'", "'.$email.'", "'.$avatar.'", "'.time().'")'))

{

//Si cela a fonctionné, on n'affiche pas le formulaire

$form = false ;

Pour la fermeture des accolades, voir le Listing 6.

Si le nom d'utilisateur spécifié est déjà pris, ou si la base de données ne peut pas être mise à jour, cette fonction renvoie false. Dans le cas contraire, elle met à jour la base de données et renvoie true.

Nous pouvons cependant remarquer que nous effectuons la connexion à la base de données avec une fonction que nous avons écrite, db_connect(). Cette fonction se contente de fournir un emplacement contenant un nom d'utilisateur et un mot de passe permettant de se connecter à la base de données sans oublier le fichier de la config.php de l'espace membre.

Si le mot de passe de la base de données doit être modifié, il suffit de le changer dans deux fichiers de notre application ainsi que les quatre autres que nous allons évoquer ci-après :.

Les fichiers à mettre à jour pour la connexion de la base de données se trouvent ci-après (uniquement pour les serveurs à distant) :

- ADD_BMS.php

- CONFIG.php

- DB_FNS.php

- MEMBER.php

- REGISTER_NEW.php

- USER_AUTH_FNS.php

Le Listing 7 du fichier db_fns.php contient le code (db_connect() ) de cette fonction pour se connecter à la base de données.

Listing 7. - La fonction db_connect() de db_fns.php - Cette fonction établit la connexion à la base de données MySQL. :

Lorsque des utilisateurs sont enregistrés, ils peuvent ouvrir une session et la refermer, en utilisant les pages classiques connexion.php et logout.php. Nous allons maintenant nous intéresser à la construction de ces pages mais avant, nous mettons le fichier config.php presque identique à db_fns.php. (à peu de chose près)

Listing 8. - Le fichier de la config.php - Ce fichier établit également la connexion à la base de données MySQL. :

Nous terminons ainsi ce deuxième chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation d'ouverture et fermeture de session, modifier et réinitialiser les mots de passe. etc.


Lire et Récupérer des données dans la BD

Travailler avec votre base de données MySQL (2ème partie) :

Lire des données dans la base de données :

L'instruction principale de SQL est SELECT. Elle est utilisée pour lire des données dans une base de données, en sélectionnant les lignes qui correspondent à certains critères, dans un tableau. L'instruction SELECT accepte beaucoup d'options, et peut être utilisée de plusieurs manières très différentes.

Voici la forme principale d'une instruction SELECT :

    SELECT items FROM tables

    [ WHERE condition ]

    [ GROUP BY group_type ]

    [ HAVING where_definition ]

    [ ORDER BY order_type ]

    [ LIMIT limit_criteria ] ;

Nous reviendrons un peu plus loin sur toutes les clauses de cette instruction. Nous allons tout d'abord commencer par examiner une requête sans aucune clause optionnelle, c'est-à-dire une simple requête qui sélectionne des éléments dans un tableau particulier. Typiquement, ces éléments sont des colonnes du tableau, mais il peut également s'agir des résultats de n'importe quelle expression MySQL. Nous reviendrons sur celles qui sont le plus utiles un peu plus loin de cette section. Cette requête renvoie le contenu des colonnes nom et ville du tableau les_clients :

    SELECT nom, ville FROM les_clients ;

Cette requête fournit le résultat suivant, en supposant que vous avez saisi les données du Listing 1, ainsi que les trois exemples qui sont montrés dans le premier chapitre, en cliquant ici et qui s'intitule "Jean_Pierre_INSERT.sql" sans oublier nos exemples.

Comme vous pouvez le constater, nous obtenons un tableau qui contient les éléments sélectionnés (nom et ville), à partir du tableau que nous avons spécifié, les_clients. Ces données sont issues de toutes les lignes du tableau les_clients.

Vous pouvez spécifier autant de colonnes que vous le souhaitez, en les mentionnant après le mot clé SELECT. Vous pouvez aussi spécifier d'autres éléments, comme le joker (*), qui symbolise toutes les colonnes du tableau spécifié. Par exemple, pour afficher toutes les colonnes et toutes les lignes du tableau les_articles_commandés, nous pouvons utiliser l'instruction suivante :

    SELECT * FROM les_articles_commandes ;

Cette commande renvoie la sortie suivante :

Récupérer des données avec des critères spécifiques :

Pour accéder à un sous-ensemble de lignes d'un tableau, nous devons spécifier plusieurs critères de sélection, à l'aide de la clause WHERE. Par exemple :

    SELECT * FROM les_commandes WHERE client_id = 5 ;

Sélectionne toutes les colonnes du tableau les_commandes et toutes les lignes dont le client_id vaut 5. Voici la sortie obtenue :

La clause WHERE spécifie les critères utilisés pour sélectionner les lignes. Dans notre exemple, nous avons sélectionné les lignes dont le client_id vaut 5. Le signe égale permet de tester l'égalité (vous remarquerez la différence avec le langage PHP). Les erreurs sont fréquentes lorsque vous les utilisez conjointement.

En plus du test d'égalité, MySQL supporte plusieurs opérateurs et expressions régulières, dont les plus courants sont présentés dans le Tableau 1. Notez bien qu'il ne s'agit pas d'une liste complète. En cas de besoin, reportez-vous au manuel du Net de MySQL.

Les trois dernières lignes de ce tableau font référence à LIKE, NOT LIKE et à REGEXP, qui effectuent des comparaisons de motifs.

Tableau 1. - Les opérateurs de comparaison utiles dans les clauses WHERE :
Opérateur | Nom (si possible) | Exemple | Description
= | égalité | client_id = 5 | Teste si deux valeurs sont égales.
> | supérieur | montant > 60.00 | Teste si une valeur est supérieure à une autre.
< | inférieur | montant < 60.00 | Teste si une valeur est inférieure à une autre.
>= | supérieur ou égal | montant >= 60.00 | Teste si une valeur est supérieure ou égale à une autre.
<= | inférieur ou égal | montant <= 60.00 | Teste si une valeur est inférieure ou égale à une autre.
! = ou <> | différent de | quantité ! = 0 | Teste si deux valeurs sont différentes.
IS NOT NULL |  | adresse IS NOT NULL | Teste si un champ contient une valeur.
IS NULL |  | adresse IS NULL | Teste si un champ ne contient aucune valeur.
BETWEEN |  | montant BETWEEN 0 AND 60.00 | Teste si une valeur se trouve dans un intervalle spécifié.
IN |  | Ville IN ("Jean", "Daniel") | Teste si une valeur se trouve dans un ensemble spécifié.
NOT IN |  | Ville NOT IN ("Jean", "Daniel") | Teste si une valeur ne se trouve pas dans un ensemble spécifié.
LIKE | comparaison de motif | nom LIKE ("Pierre %") | Teste si une valeur correspond à un motif spécifié.
NOT LIKE | comparaison de motif | nom NOT LIKE ("Pierre %") | Teste si une valeur ne correspond pas à un motif spécifié.
REGEXP | expression régulière | nom REGEXP | Teste si une valeur correspond à une expression régulière.

LIKE se sert de la comparaison de motif de SQL. Les motifs peuvent contenir du texte classique, plus les caractères % et _ . % remplace n'importe quelle chaîne de caractères, et _ remplace n'importe quel caractère. Dans MySQL, ces motifs ne respectent pas la casse. Par exemple, 'Pierre %' correspond à n'importe quelle valeur commençant par 'Pierre'.

Le mot clé REGEXP est utilisé pour les comparaisons avec des expressions régulières. MySQL se sert des expressions régulières POSIX. Vous pouvez aussi vous servir de RLIKE à la place de REGEXP, qui en est un synonyme. Les expressions régulières sont également utilisées dans PHP (voir 4ème leçon, 1ère et 2ème partie).

Il est possible de tester plusieurs critères de cette manière, et de les associer avec AND et OR. Par exemple :

    SELECT * FROM les_commandes WHERE client_id = 4 OR client_id = 3 ;

Ce qui vous donne ceci :

Requete SELECT les commandes WHERE client_id = 4 OR client_id = 3 ;.png

Récupérer des données dans plusieurs tableaux :

Il arrive souvent que pour répondre à une question posée à la base de données, il faille récupérer des données dans plusieurs tableaux. Par exemple, si vous souhaitez connaître les clients qui ont passé des commandes au cours de ce mois-ci, vous devez examiner le tableau les_clients et le tableau les_commandes. Si vous souhaitez également savoir précisément ce qu'ils ont commandé, vous devez également examiner le tableau les_articles_commandés.

Ces éléments se trouvent dans différents tableaux puisqu'ils correspondent à des objets réels différents. C'est l'un des principes de conception que nous avons vus dans les leçons précédentes, cliquez ici si vous voulez revoir certaines leçons.

Pour rassembler ces informations avec SQL, vous devez effectuer une opération appelée "fusion". Cela revient simplement à réunir plusieurs tableaux, en fonction des relations qui existent entre leurs données. Par exemple, si nous souhaitons afficher les commandes effectuées par Michael-Pierre ROBERT, nous devons commencer par chercher le client_id de Michael-Pierre ROBERT dans le tableau les_clients, puis chercher les commandes correspondant à ce client_id dans le tableau les_commandes.

Bien que les opérations de fusion soient conceptuellement assez simples, il s'agit en fait d'une des parties les plus subtiles et les plus complexes de SQL. MySQL implémente plusieurs types de fusions différentes, destinées chacune à une utilisation particulière.

Fusion simple de deux tableaux :

Commençons par étudier le code SQL pour la requête dont nous venons de parler, à propos de Michael-Pierre ROBERT.

    SELECT les_commandes . commande_id, les_commandes . montant, les_commandes . date

    FROM les_clients, les_commandes

    WHERE les_clients . nom = 'Michael-Pierre ROBERT'

    AND les_clients . client_id = les_commandes . client_id ;

Le résultat de cette requête est le suivant :

requete SELECT les commandes commande_id.png

Nous pouvons remarquer plusieurs choses intéressantes.

Tout d'abord, comme il faut réunir les informations des deux tableaux pour répondre à cette requête, nous avons listé ces deux tableaux.

Nous avons également spécifié un type de fusion, même si nous ne le savons pas. La virgule entre les noms des tableaux est équivalente à INNER JOIN ou à CROSS JOIN. Il s'agit d'un type de fusion que l'on appelle parfois une "fusion complète", ou encore le "produit cartésien" des deux tableaux. Cela signifie littéralement : "A partir des tableaux spécifiés, faire un seul grand tableau, qui doit contenir une ligne pour chaque combinaison possible des lignes des tableaux spécifiés, que cela ait un sens ou non." En d'autres termes, nous obtenons un tableau contenant toutes les lignes du tableau les_clients associées à toutes les lignes du tableau les_commandes, quelles que soient les commandes effectuées par les clients.

Cette opération n'a pas beaucoup de sens dans la plupart des cas. En effet, on souhaite le plus souvent retenir uniquement les lignes qui ont un sens, c'est-à-dire, les commandes effectuées par un client associées à ce même client.

Pour obtenir ce résultat, il suffit d'ajouter une "condition de fusion" dans la clause WHERE, qui est une instruction conditionnelle spéciale. Dans notre cas, notre condition de fusion est la suivante :

    les_clients . client_id = les_commandes . client_id

En d'autres termes, comme ceci :

    SELECT les_commandes . commande_id, les_commandes . montant, les_commandes . date

    FROM les_clients, les_commandes

    WHERE les_clients . client_id = les_commandes . client_id

    AND les_clients . client_id = les_commandes . client_id ;

Ce qui donne un peu plus d'informations comme ci-après :

Elle demande à MySQL de ne placer dans le tableau final que les lignes dont le client_id du tableau les_clients correspond au client_id du tableau les_commandes.

En ajoutant cette condition de fusion à notre requête, nous sommes passés à un autre type de fusion, appelée "fusion d'équivalence".

Vous avez également remarqué la notation avec le point, permettant de spécifier sans ambiguïté le tableau dont les colonnes proviennent, c'est-à-dire que les_clients . client_id fait référence à la colonne client_id du tableau les_clients, et les_commandes . client_id fait référence à la colonne client_id du tableau les_commandes.

Cette notation est nécessaire si le nom d'une colonne est ambigu, c'est-à-dire s'il apparaît dans plusieurs tableaux.

De plus, elle peut également être utilisée pour lever les ambiguïtés sur les noms des colonnes de plusieurs bases de données. Dans cet exemple, nous nous sommes servi de la notation tableau.colonne, mais il est aussi possible d'y ajouter la base de données (base_de_donnees.tableau.colonne), par exemple, pour tester une condition comme celle-ci :

    books.les_commandes.client_id = autre_db.les_commandes.client_id ;

Enfin, vous pouvez vous servir de cette notation pour toutes les références de colonnes dans une requête. C'est généralement une bonne idée, surtout lorsque vos requêtes deviennent un peu plus complexes. Ce n'est pas imposé par MySQL, mais cela facilite beaucoup la lisibilité et la maintenance de vos requêtes. Vous remarquerez que nous avons respecté cette convention dans le reste de la requête précédente, par exemple dans la condition :

    les_clients.nom = 'Michael-Pierre ROBERT' ;

La colonne nom se trouve uniquement dans le tableau les_clients, donc, on pourrait penser que cette notation est superflue, mais elle clarifie la syntaxe.

Fusion de plus de deux tableaux :

Cette opération n'est pas plus complexe que la fusion de deux tableaux. D'une manière générale, les tableaux doivent être fusionnés avec des conditions de fusion. Vous pouvez considérer que cela revient à respecter les relations qui existent entre les données des tableaux.

Par exemple, si nous souhaitons connaître les clients qui ont commandé des livres sur Electrotechnique pour les Professeurs (éventuellement pour pouvoir leur envoyer des informations sur un nouveau livre sur Electrotechnique pour les Professeurs), nous devons suivre ces relations dans plusieurs tableaux.

Nous devons commencer par repérer les clients qui ont passé au moins une commande contenant sur les_articles_commandés correspondant à un livre sur Electrotechnique pour les Professeurs. Pour passer du tableau les_clients au tableau les_commandes, nous pouvons nous servir du client_id, comme nous l'avons déjà fait. Pour passer du tableau les_commandes au tableau les_articles_commandés, nous pouvons utiliser commande_id. Pour obtenir dans le tableau les_articles_commandés un livre spécifique du tableau Books, nous pouvons nous servir du numéro ISBN. Après avoir établi toutes ces relations, nous pouvons chercher les livres dont le titre contient "Electrotechnique pour les Professeurs", et renvoyer les noms des clients qui ont acheté l'un de ces livres.

Voyons maintenant le code de cette requête :

    SELECT les_clients . nom

    FROM les_clients, les_commandes, les_articles_commandes, les_livres

    WHERE les_clients . client_id = les_commandes . client_id

    AND les_commandes . commande_id = les_articles_commandes . commande_id

    AND les_articles_commandes . isbn = les_livres . isbn

    AND les_livres . titre like "%Electrotechnique pour les Professeurs%" ;

Cette requête renvoie le résultat suivant :

Vous remarquerez que nous avons suivi les données dans quatre tableaux différents, et pour faire cela avec une fusion d'équivalence, nous avons besoin de trois conditions de fusion différentes. Comme il faut généralement une condition de fusion pour chaque paire de tableau que vous souhaitez fusionner, il y a au total une fusion de moins que le nombre de tableaux à fusionner. Cette règle est assez utile pour déboguer les requêtes qui ne fonctionnent pas. Vérifiez vos conditions de fusion et assurez-vous que vous respectez bien les enchaînements nécessaires.

Trouver les lignes qui ne correspondent pas :

Le principal autre type de fusion que l'on utilise dans MySQL est la fusion de suppression.

Dans les exemples précédents, seules les lignes vérifiant les conditions dans tous les tableaux étaient retenues. Il arrive cependant que l'on ait besoin des lignes qui ne correspondent pas à ces conditions, par exemple, pour rechercher les clients qui n'ont passé aucune commande, ou les livres qui n'ont jamais été achetés.

La méthode la plus simple pour répondre à ce type de question dans MySQL consiste à utiliser une fusion de suppression. Une fusion de suppression renvoie les lignes satisfaisant une condition de fusion spécifiée, entre deux tableaux. S'il n'y a aucune ligne correspondante dans le tableau, une ligne est ajoutée dans le tableau des résultats, contenant la valeur NULL dans la colonne appropriée.

Prenons un exemple :

    SELECT les_clients . client_id, les_clients . nom, les_commandes . commande_id

    FROM les_clients left join les_commandes

    ON les_clients . client_id = les_commandes . client_id ;

Cette requête SQL se sert d'une fusion de suppression pour fusionner les tableaux les_clients et les_commandes. Vous remarquerez que la fusion de suppression suit une syntaxe légèrement différente de celle de la condition de fusion : dans notre cas, la condition du fusion se trouve dans une clause ON spéciale de l'instruction SQL.

Voici le résultat de cette requête :

Les Clients n ont passe aucune Commande.png

Cette sortie montre qu'il existe aucune commande_id pour les clients Jean-Patrick BEESSE, Michaelle-Patricia CORGNO, Jennifer-Josiane LEDUC et Julie DUPONDRA, parce que les commande_id de ces clients valent NULL.

Si nous souhaitons trouver les clients qui n'ont passé aucune commande, il suffit de chercher ces valeurs NULL dans le champ de la clé primaire du tableau correspondant (dans ce cas commande_id), puisque ce champ ne devrait pas être NULL :

    SELECT les_clients . client_id, les_clients . nom

    FROM les_clients LEFT JOIN les_commandes

    USING (client_id)

    WHERE les_commandes . commande_id IS NULL ;

Et voici le résultat obtenu :

Les Clients n ont passe aucune Commande_2.png

Vous remarquerez également que nous nous sommes servi d'une syntaxe différente pour la condition de fusion dans cet exemple. Les fusions de suppression supportent soit la syntaxe ON que nous avons utilisée dans le premier exemple, soit la syntaxe USING du second exemple. La syntaxe USING ne spécifie pas le tableau d'où provient l'attribut de fusion, cest pourquoi les colonnes des deux tableaux doivent posséder le même nom si vous voulez utiliser USING.

Utiliser d'autres noms pour les tableaux - les alias :

Il est souvent pratique, voire essentiel, de pouvoir faire référence aux tableaux avec d'autres noms, que l'on appelle des "alias". Vous pouvez les créer au début d'une requête, et les utiliser dans tout le reste de cette requête. Ils permettent souvent de simplifier la saisie des noms des tableaux. Considérons la grosse requête que nous venons de voir, récrite avec des alias :

    SELECT c . nom

    FROM les_clients as c, les_commandes as o, les_articles_commandes as oi, les_livres as b

    WHERE c . client_id = o . client_id

    AND o . commande_id = oi . commande_id

    AND oi . isbn = b . isbn

    AND b . titre LIKE '%Electrotechnique pour les Professeurs%'

Et voici le résultat obtenu :

Lorsque nous déclarons les tableaux que nous allons utiliser, nous ajoutons une clause AS pour déclarer l'alias d'un tableau. Il est également possible de définir des alias pour des colonnes, mais nous y reviendrons lorsque nous verrons les fonctions d'agrégation.

Il faut passer par les alias pour fusionner un tableau avec lui-même. Cela a l'air plus difficile et plus étrange que cela ne l'est en réalité. Cette approche peut être utile, si, par exemple, nous voulons trouver dans un tableau les lignes qui possèdent des valeurs en commun. Ainsi, pour trouver les clients qui habitent dans la même ville (éventuellement pour diffuser des publicités par exemple), nous pouvons affecter deux alias au même tableau (les_clients) :

    SELECT c1 . nom, c2 . nom, c1 . ville

    FROM les_clients AS c1, les_clients AS c2

    WHERE c1 . ville = c2 . ville

    AND c1 . nom != c2 . nom ;

Dans cette requête, nous faisons comme si le tableau les_clients était en fait deux tableaux différents, c1 et c2, et nous effectuons une fusion sur la colonne ville. Vous remarquerez que nous avons également besoin de la deuxième condition, c1 . nom != c2 . nom, pour éviter que chaque client ne soit détecté.

Résumé des fusions :

Les différents types de fusions sont résumés dans le Tableau 2. Il en existe quelques autres, mais ce tableau rassemble les fonctions que vous utiliserez le plus souvent.

Tableau 2. - Les types de fusions dans MySQL :
Nom | Description
Produit cartésien | Toutes les combinaisons de toutes les lignes des tableaux à fusionner. Ce type de fusion est choisi en spécifiant une virgule entre les noms des tableaux, et en ne spécifiant aucune clause WHERE.
Fusion complète | Comme ci-dessus.
Fusion croisée | Comme ci-dessus. Peut également être utilisé en spécifiant les mots clés CROSS JOIN entre les noms des tableaux à fusionner.
Fusion interne | Sémantiquement équivalent à la virgule. Peut également être spécifié à l'aide des mots-clés INNER JOIN. Sans condition WHERE, équivalent à une fusion complète. Généralement, vous spécifierez donc une condition WHERE pour en faire une fusion interne.
Fusion d'équivalence | Utilise une expression conditionnelle avec un = pour associer les lignes des différents tableaux de la fusion. Dans SQL, c'est une fusion avec une clause WHERE.
Fusion de suppression | Tente d'associer des lignes provenant des tableaux spécifiés, et remplit les lignes ne correspondant pas avec les valeurs NULL. Utilisé dans SQL avec des mots clés LEFT JOIN. Permet de trouver des valeurs manquantes. Vous pouvez utiliser de la même manière RIGHT JOIN.

Nous terminons ainsi ce deuxième chapitre (2ème partie de cette leçon) et nous verrons dans le prochain, l'usage pour Récupérer les Données dans un Ordre Particulier, Groupement et Agrégation des données, choisir les lignes à renvoyer, Mise à jour des enregistrements de la base de données et enfin, les Modifications des Tableaux après leur Création et Suppression des enregistrements dans la Base de Données.


Utilisation des Fonctions en PHP

Utilisation de fonctions, en PHP (2ème partie) :

Les fonctions existent dans la plupart des langages de programmation. Elles s'emploient pour séparer du code qui accomplit une tâche unique et bien définie. Les fonctions rendent le code plus lisible, et permettent de réutiliser le code chaque fois qu'une même tâche doit être accomplie.

Une fonction est un module de code autonome auquel est associée une interface d'appel, qui accomplit une certaine tâche, et qui renvoie éventuellement un résultat.

Nous avons déjà étudié diverses fonctions. Dans les chapitres précédents, nous avons régulièrement invoqué des fonctions prédéfinies dans PHP. Par ailleurs, nous avons nous-même écrit quelques fonctions simples, sans toutefois entrer dans les détails. Dans cette section du second chapitre, nous allons nous pencher plus attentivement sur l'invocation et l'écriture de fonctions.

Invocation (appel) de fonctions :

Le plus simple appel de fonction envisageable est le suivant :

    ma_fonction ;

Cette ligne de code invoque la fonction dénommée ma_fonction, qui ne prend pas de paramètre. Elle ignore toute valeur éventuellement renvoyée par la fonction.

Nombre de fonctions s'invoquent exactement de cette manière. Par exemple, c'est le cas de la fonction phpinfo(), qui est très utile lors de tests parce qu'elle affiche la version installée de PHP, des informations relatives à PHP, la configuration du serveur Web et les valeurs de diverses variables PHP et serveur. Cette fonction ne prend aucun paramètre, et la valeur qu'elle renvoie et le plus souvent ignorée. L'invocation de la fonction phpinfo() est donc souvent implémentée de la manière suivante :

    phpinfo() ;

Une portion d'un aperçu de phpinfo() ci-après : (et nous ne pouvons mettre toutes les informations de cette fonction pour manque de place).

La plupart des fonctions requièrent un ou plusieurs paramètres, qui fournissent à la fonction les informations nécessaires à l'accomplissement de la tâche, et qui vont influencer le résultat de l'exécution de la fonction. Les paramètres, également appelés arguments, sont passés à une fonction sous la forme de données, ou de noms de variables contenant les données, placées entre parenthèses à la suite du nom de la fonction. L'invocation d'une fonction prenant un seul paramètre s'implémente comme suit :

    ma_fonction("parametre") ;

Dans ce cas, le paramètre spécifié est une chaîne contenant seulement le mot paramètre. Les appels de fonction qui suivent sont également valident, selon la fonction invoquée :

    ma_fonction(4) ;

    ma_fonction(7.984) ;

    ma_fonction($variable) ;

Dans la dernière de ces trois lignes de code, $variable peut être une variable PHP de tout type, y compris un tableau. ([]).

Les paramètres peuvent être de tous types, mais en général, chaque fonction requiert un, ou des paramètres, avec des types de données spécifiques.

Le "prototype" d'une fonction décrit le nombre de paramètres requis, ainsi que la signification et le type de données de chaque paramètre. Cette leçon donne généralement le prototype de chaque fonction décrite. Vous trouverez, en outre, le jeu exhaustif des prototypes des fonctions PHP que nous avions examiné et fort bien utile dédié à PHP, et situé à l'URL ci-après : prototypes des fonctions PHP.

Le prototype de la fonction fopen() est le suivant :

    int fopen (string nom_du_fichier, string mode, [int utiliser_include_path] );

Le prototype d'une fonction fournit de précieuses indications sur la fonction, qu'il est important de savoir interpréter. Dans le prototype de la fonction fopen(), le terme int placé avant le nom de la fonction indique que la fonction renvoie un nombre entier. Les paramètres (ou arguments) de la fonction sont spécifiés entre parenthèses, fopen() prend trois paramètres, décrits par le prototype de la fonction. Les paramètres mode et nom_du_fichier sont des chaînes, tandis que le paramètre utiliser_include_path est un nombre entier. La présence de crochets de part et d'autre du paramètre utiliser_include_path indique que ce dernier est optionnel. Vous pouvez fournir une valeur à un paramètre optionnel, ou bien choisir de l'ignorer, auquel cas, l'interpréteur PHP utilisera sa valeur par défaut.

Après lecture du prototype de la fonction fopen(), nous pouvons affirmer que, dans le fragment de code qui suit, l'appel de la fonction fopen() est valide :

    $Nom = "Mon_fichier.txt" ;

    $File_mode = "r" ;

    $fp = fopen($Nom, $File_mode) ;

Ce code invoque la fonction dénommée fopen(). La valeur renvoyée par cette dernière est ensuite stockée dans la variable $fp. Une variable dénommée $Nom est passée à la fonction fopen() comme premier argument. Cette variable contient une chaîne représentant le nom du fichier à ouvrir. Le deuxième argument passé à la fonction fopen() est une variable appelée $File_mode, et qui contient une chaîne représentant le mode d'ouverture du fichier. Dans cet exemple d'invocation de la fonction fopen(), le troisième paramètre n'est pas fourni.

Appel d'une fonction non définie :

L'appel d'une fonction qui n'existe pas provoque la génération d'un message d'erreur, tel que celui montré à la figure 1.

Les messages d'erreur affichés par l'interpréteur PHP sont généralement très utiles. Celui de la figure 1, nous indique exactement le contexte dans lequel s'est produite l'erreur, c'est-à-dire le nom du fichier, le numéro de la ligne du script, et le nom de la fonction qui a été invoquée et qui n'existe pas. Ces indications permettent, en principe, de corriger facilement et rapidement l'erreur survenue.

A l'affichage d'un tel message d'erreur, vous devez examiner deux questions :

Le nom de la fonction est-il correctement orthographié dans le script ?

La fonction invoquée existe-t'elle dans la version de PHP utilisée ?

Les noms des fonctions sont parfois difficiles à mémoriser. Par exemple, certaines fonctions prédéfinies dans PHP ont des noms composés de deux mots séparés par un caractère de soulignement comme strip_tags(), tandis que d'autres, ont des noms formés de deux mots accolés comme stripslashes(). La présence d'une faute d'orthographe dans le nom d'une fonction provoque l'erreur montrée à la figure 1.

Nombre de fonctions décrites dans cette leçon n'existent pas dans la version 3.0 de PHP : nous partons, en effet, ici du principe que vous êtes au moins équipé de la nouvelle version supérieure à 5.3.8. Chaque nouvelle version de PHP apporte son lot de nouvelles fonctions, qui enrichissent la fonctionnalité et la performance du langage, et justifient de ce fait une mise à jour pour tous ceux utilisant la version précédente. Vous pourrez trouver dans le manuel en ligne de PHP en cliquant ici, la date d'ajout de chaque fonction disponible. L'invocation d'une fonction non déclarée dans la version PHP utilisée provoque l'erreur dont le message est montré à la figure 1. Et pour finir, nous allons expliquer, pourquoi créer ses propres fonctions ? Et on verra dans ce chapitre, les structures de base d'une fonction par exemple.

La Casse et Noms de Fonctions :

Notez que les appels de fonctions ne sont pas sensibles à la casse (emploi de majuscules et minuscules). Ainsi, les appels de fonction_nom(), Fonction_Nom(), et FONCTION_NOM() sont tous valides, et conduisent au même résultat. Vous êtes libre de choisir la casse qui vous convient, et que vous jugez plus facile à lire. Veillez toutefois à rester cohérent. Dans cette leçon, comme dans la plupart des ouvrages de programmation, la convention adoptée consiste à placer tous les noms de fonctions en minuscules.

Les noms de fonction se comportent différemment des noms de variables. Les noms de variables sont, eux, sensibles à la casse, de telle sorte que $Name et $name désignent deux variables différentes, tandis que Name() et name() désignent la même fonction.

Au cours des leçons précédentes, nous avons été amenés à étudier et à utiliser nombre de fonctions prédéfinies dans le langage PHP. Toutefois, la réelle puissance d'un langage de programmation tient dans la possibilité de créer ses propres fonctions d'utilisateur.

Pourquoi définir ses propres fonctions ? :

Grâce aux fonctions prédéfinies dans PHP, vous pouvez interagir avec des fichiers, manipuler une base de données (que l'on verra par la suite au cours des prochains chapitres), créer des images, et établir la connexion avec d'autres serveurs. Malgré la richesse des possibilités qui sont ainsi offertes, le programmeur se trouve fréquemment en situation, d'implémenter une tâche pour laquelle aucune fonction n'a été prédéfinie dans PHP.

Il est heureusement possible de créer des "fonctions utilisateur" (personnalisées), en sus des fonctions prédéfinies dans PHP, pour accomplir toute tâche de votre goût. Le code du programmeur est souvent une combinaison de fonctions existantes et de logique personnalisée accomplissant des tâches particulières. Lorsque vous êtes amené à écrire un bloc de code pour implémenter une tâche, que vous prévoyez d'accomplir en d'autres points de votre script, voire dans d'autres scripts, vous avez tout intérêt à déclarer ce bloc de code en tant que fonction.

Déclarer une fonction permet d'utiliser du code personnalisé à la manière des fonctions prédéfinies dans PHP : il suffit d'invoquer la fonction utilisateur, en lui fournissant les paramètres requis. Vous pouvez ainsi appeler et réutiliser la même fonction plusieurs fois dans un même script.

Structure de base d'une fonction :

Une déclaration de fonction crée, ou "déclare", une nouvelle fonction. Une déclaration commence par le mot clé function, spécifie le nom de la fonction, les paramètres requis, et contient le code à exécuter à chaque invocation de la fonction.

La déclaration d'une fonction triviale s'effectue de la manière suivante :

     function ma_fonction()

    {

       echo "Ma fonction a &eacute;t&eacute; invoqu&eacute;e." ;

    }

Cette déclaration de fonction commence par function, de sorte qu'humains et l'interpréteur PHP soient informés que le code qui suit est celui d'une fonction utilisateur. Le nom de la fonction étant ma_fonction, nous pouvons invoquer notre nouvelle fonction au moyen de l'instruction suivante :

    ma_fonction() ;

Comme vous l'avez probablement deviné, l'appel de cette fonction se traduit par l'affichage dans la fenêtre du navigateur du texte : "Ma fonction a été invoquée.".

Alors que les fonctions prédéfinies dans PHP sont utilisables dans tous les scripts PHP, les fonctions utilisateur ne sont utilisables qu'à partir des scripts dans lesquels elles ont été déclarées. Il est recommandé de rassembler dans un même fichier toutes les fonctions utilisateur couramment utilisées. Cette astuce permet en effet, au programmeur d'accéder à toutes ses fonctions personnalisées par une simple instruction require() ou include() insérée dans chacun des scripts.

Au sein d'une déclaration de fonction, le code accomplissant la tâche requise doit être placé entre accolades. Ce code peut contenir tout ce qui est légal dans un script PHP, y compris des appels d'autres fonctions, des déclarations de nouvelles variables ou fonctions, des instructions require() ou include(), et du plein HTML. Lorsque, au sein d'une fonction, il est nécessaire de quitter PHP et de taper du plein HTML, il suffit de procéder comme en tout autre point d'un script, en plaçant une balise PHP de fermeture avant le code HTML.

Le code qui suit est une variante légale de l'exemple précédent, et qui conduit au même résultat :

    <?PHP

        function ma_fonction()

          {

    ?>

       <BR /> <font face = 'Arial'> Ma fonction a &eacute;t&eacute; invoqu&eacute;e. </font>

    <?PHP

          }

       ma_fonction() ;

    ?>

Veuillez noter que le code PHP est contenu entre des paires de balises PHP d'ouverture et de fermeture. Dans la plupart des fragments de code donnés en exemple dans cette leçon, ces balises ne sont pas montrées. Nous les avons données dans cet exemple, parce qu'elles y sont indispensables.

Attribution d'un nom à une fonction :

Votre souci principal, lors du choix d'un nom pour une fonction utilisateur, devrait être d'adopter un nom explicite. Par exemple, pour une fonction créant un en-tête de page Web, les noms pageheader() ou page_header() seraient appropriés.

Les quelques restrictions à prendre en compte lors du choix des noms de fonctions sont les suivantes :

Ne donnez pas à une fonction un nom déjà attribué à une autre fonction.

Un nom de fonction ne peut contenir que des lettres, des chiffres et des caractères de soulignement.

Un nom de fonction ne doit pas commencer par un chiffre.

Evitez les ponctuations ou les accents aigu ainsi que les accents grave dans les fonctions et programmes en PHP, sinon pose problème dans certain cas.

Nombre de langages de programmation autorisent la réutilisation des noms de fonctions. On parle alors de "surcharge de fonction" (overloading). PHP interdit toutefois la surcharge de fonction, c'est-à-dire qu'il ne permet pas de donner à une fonction utilisateur le même nom qu'une fonction prédéfinie ou qu'une autre fonction utilisateur. Notez que si chaque script PHP "connaît" toutes les fonctions PHP prédéfinies, les fonctions utilisateur ne sont connues que dans les seuls scripts où elles sont déclarées. Par conséquent, rien ne vous empêche de réutiliser le nom d'une de vos fonctions utilisateur pour l'attribuer à une autre fonction, stockée dans un autre fichier. Cette pratique est toutefois source de confusion, et devrait être évitée.

Les différents noms qui suivent sont tous légaux :

nom()

nom2()

nom_trois()

_nomquatre()

_nom_cinq()

Tandis que ceux-ci sont illégaux :

10nom()

nom-sept()

fopen()

(Le dernier de ces noms aurait été légal s'il n'était déjà attribué à une fonction prédéfinie.)

Paramètres :

Pour accomplir la tâche pour laquelle elles ont été conçues, la plupart des fonctions requièrent que un ou plusieurs paramètres (arguments) leur soient fournis. Un paramètre permet de passer des données à une fonction. Voici un exemple d'une fonction qui prend un tableau unidimensionnel comme paramètre, et l'affiche sous une forme tabulaire :

    <?PHP

        function create_table($data)

          {

       echo " <BR /> <CENTER> <TABLE BORDER = '2'> " ;

     reset($data) ; // Souvenez-vous que cette fonction permet de pointer le début des données.

     $value = current($data) ;

     while($value)

          {

       echo "<tr> <td> $value </td> </tr> \n" ;

     $value = next ($data) ;

          }

       echo "</CENTER> </TABLE>" ;

          }

Si la fonction create_table() est invoquée de la manière suivante :

    $mon_tableau = array("Ligne une." , "Ligne deux." , "Ligne trois." , "Ligne quatre.") ;

    create_table($mon_tableau) ;

    ?>

Alors le résultat obtenu, est celui montré ci-après : pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

En utilisant un paramètre pour la fonction create_table(), nous avons pu manipuler au sein de cette dernière des données créées hors de la fonction (en l'occurence le tableau $data).

Tout comme les fonctions prédéfinies, les fonctions définies par l'utilisateur peuvent prendre plusieurs paramètres, et peuvent également prendre des paramètres optionnels. La fonction create_table() peut être améliorée de diverses manières, par exemple, en permettant à celui qui l'invoque de spécifier la bordure ou d'autres attributs du tableau. Voici un exemple d'une version améliorée de la fonction create_table(), très semblable à la précédente, si ce n'est qu'elle permet d'ajuster, optionnellement, la largeur de la bordure, l'espacement entre les cellules et l'espacement entre le contenu des cellules et la bordure :

    <?PHP

        function amelioration_tableau ($data, $border = 2, $cellpadding = 6, $cellspacing = 6)

          {

       echo " <BR /> <CENTER> <TABLE BORDER = $border cellpadding = $cellpadding "

        . " cellspacing = $cellspacing /> " ;

     reset($data) ; // Souvenez-vous que cette fonction permet de pointer le début des données.

     $value = current($data) ;

     while($value)

          {

       echo "<tr> <td> $value </td> </tr> \n" ;

     $value = next ($data) ;

          }

       echo "</CENTER> </TABLE>" ;

          }

    $mon_tableau = array("Ligne une." , "Ligne deux." , "Ligne trois." , "Ligne quatre.") ;

    amelioration_tableau ($mon_tableau) ; // Appel de la fonction amelioration_tableau().

    ?>

Le résultat obtenu, est celui montré ci-après : pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Le premier paramètre de la fonction amelioration_tableau() est obligatoire, comme dans le cas de la fonction create_table() de l'exemple précédent. Les trois paramètres suivants sont optionnels, parce que des valeurs par défaut sont spécifiées pour ces paramètres dans la déclaration de la fonction. L'appel de la fonction amelioration_tableau() peut produire un résultat comparable à celui de [l'exemple 1] précédent, s'il est formulé de la manière suivante :

    amelioration_tableau ($mon_tableau) ;

Pour une présentation plus aérée des données du tableau. Nous pourrions invoquer amelioration_tableau() de la manière suivante :

    amelioration_tableau ($mon_tableau, 5, 8, 8) ; // Appel de la fonction amelioration_tableau().

Lorsque des paramètres sont optionnels, il n'est pas indispensable d'en fournir des valeurs. L'interpréteur PHP affecte les paramètres de gauche à droite.

Notez bien qu'il n'est pas possible de "sauter" un paramètre optionnel lors d'un appel de fonction, pour spécifier un autre paramètre optionnel venant à sa droite dans la définition de la fonction. Dans l'exemple considéré ici, il est nécessaire de passer une valeur pour le paramètre cellpadding pour pouvoir passer une valeur pour le paramètre cellspacing. Le non-respect de cette règle est à l'origine de nombreuses erreurs de programmation. Par ailleurs, cette règle est la raison pour laquelle les paramètres optionnels sont toujours spécifiés en dernier dans la liste des paramètres.

L'appel de fonction suivant :

    amelioration_tableau ($mon_tableau, 5) ;

Est tout à fait légal, et conduit à une bordure large de 5 pixels et à des espacements entre cellules et au sein des cellules ajustés sur les valeurs par défaut.

Portée d'une variable :

Vous avez peut-être noté, dans certains exemples de cette leçon ou des chapitres précédents, que lorsque des variables sont nécessaires dans du code enregistré dans un fichier chargé via une instruction require() ou include(), nous les déclarons simplement dans le script avant l'instruction require() ou include(). Par contre, avec une fonction, les variables requises au sein de la fonction doivent être explicitement passées à la fonction sous forme de paramètres. Cette différence s'explique en partie, par le fait qu'il n'existe pas de mécanisme permettant de passer explicitement des variables à des fichiers de type "include", et en partie parce que la portée d'une variable est différente dans le contexte d'une fonction.

La portée d'une variable définit les emplacements du code où une variable est visible et utilisable. Chaque langage de programmation peut avoir ses propres règles, en matière de portée des variables. Les règles du langage PHP sont relativement simples sur ce point :

La portée d'une variable déclarée au sein d'une fonction s'étend de l'instruction à partir de laquelle est déclarée la variable jusqu'à l'accolade de fermeture de la fonction. La portée est alors dite "limitée à la fonction, et les variables sont qualifiées de "locales".

La portée d'une variable déclarée hors d'une fonction s'étend de l'instruction dans laquelle la variable a été déclarée jusqu'à la fin du fichier, exception faite des fonctions. La portée est alors "globale", et les variables elles-mêmes sont qualifiées de globales.

L'usage d'instructions require() et include() n'affecte pas la portée des variables. Si une telle instruction est mise en œuvre au sein d'une fonction, la portée est limitée à la fonction. Si une instruction require() ou include() est mise en œuvre hors de toute fonction, la portée est globale.

Le mot clé global peut être employé pour spécifier explicitement qu'une variable définie ou utilisée au sein d'une fonction doit avoir une portée globale.

Une variable peut être supprimée explicitement via un appel de la fonction unset ($nom_variable). Après qu'une variable a été traitée par la fonction unset(), la portée de la variable n'est plus définie.

Les quelques exemples qui suivent vous aideront à mieux saisir les implications de ces règles.

L'exécution du code donné ci-dessous ne produit aucun résultat. Une variable appelée $var y est déclarée au sein d'une fonction dénommée fonc(). Parce que cette variable est déclarée au sein d'une fonction fn() par exemple, sa portée est limitée à la fonction, et elle existe seulement entre le point où elle a été déclarée et la fin de la fonction. Lorsque $var est mise en œuvre hors de la fonction fn(), l'interpréteur PHP crée une nouvelle variable appelée $var. Cette nouvelle variable est de portée globale, et reste visible jusqu'à la fin du fichier. Comme $var est uniquement utilisée dans une simple instruction echo, elle ne stocke aucune valeur.

    function fn()

       {

          $var = " Je suis parti ! " ;

       }

    echo $var ;

Voici la situation inverse : une variable est déclarée hors d'une fonction fn(), et nous tentons de l'utiliser au sein de la fonction fn().

    function fn()

       {

    echo " Je suis à l'intérieur de la fonction, \$var = " . $var . " <BR /> " ;

    $var = " Je suis parti (2) " ; // Variable locale.

    echo " Je suis à l'intérieur de la fonction, \$var = " . $var . " <BR /> " ;

       }

    $var = " Je suis parti (1) " ; // Variable portée globale

    fn() ; // On fait appel à la fonction.

    echo " Je suis en dehors de la fonction, \$var = " . $var . " <BR /> " ;

L'exécution de ce fragment de code conduit au résultat suivant :

Je suis à l'intérieur de la fonction, $var =

Je suis à l'intérieur de la fonction, $var = Je suis parti (2)

Je suis en dehors de la fonction, $var = Je suis parti (1)

Les fonctions n'étant exécutées que lorsqu'elles sont appelées, la première instruction exécutée dans ce code est $var = " Je suis parti (1) " ;. Une variable appelée $var est alors créée. Cette variable est de portée globale, et contient la chaîne "Je suis parti (1)". L'interpréteur PHP exécute ensuite l'appel de la fonction fn(), en exécutant dans l'ordre les lignes qui constituent la déclaration de la fonction. La première de ces lignes fait référence à une variable dénommée $var. Au moment de l'exécution de cette ligne, l'interpréteur PHP ignore la variable $var déjà créée, et crée une nouvelle variable dont la portée se limite à la fonction fn(). C'est l'affichage du contenu de cette nouvelle variable au moyen de l'instruction echo qui produit la première ligne dans la fenêtre du navigateur.

La ligne qui vient ensuite dans la déclaration de la fonction donne à $var le contenu " Je suis parti (2) ". Etant donné que cette ligne de code appartient à la fonction, elle modifie la valeur de la variable $var locale, et non pas celle de la variable globale. La deuxième ligne affichée dans le navigateur met en évidence ce fonctionnement.

Une fois que s'achève l'exécution de la fonction, la dernière ligne de notre petit script est exécutée. Cette instruction echo finale montre que la valeur de la variable globale $var n'a pas été affectée par l'exécution de la fonction fn()

Pour obtenir qu'une variable créée au sein d'une fonction soit de portée globale, nous devons spécifier le mot clé global, comme suit :

    function fn()

       {

    global $var ;

    $var = " Je suis parti " ; // Variable globale.

    echo " Je suis à l'intérieur de la fonction, \$var = " . $var . " <BR /> " ;

       }

    fn() ; // On fait appel à la fonction.

    echo " Je suis en dehors de la fonction, \$var = " . $var . " <BR /> " ;

Dans cet exemple, la variable $var est explicitement définie comme globale. Il s'ensuit que, après l'appel de la fonction fn(), la variable persite hors de la fonction. L'exécution de ce fragment de code produit l'affichage suivant :

Je suis à l'intérieur de la fonction, $var = Je suis parti

Je suis en dehors de la fonction, $var = Je suis parti

Notez bien que la portée de la variable commence au point où la ligne global $var ; est exécutée. Nous aurions aussi bien pu placer la déclaration de la fonction après qu'avant la ligne contenant l'appel de la fonction. Une déclaration de fonction peut être indifféremment placée, en n'importe quel point d'un script. Par contre, la position de l'appel de la fonction est importante, puisqu'elle définit l'endroit du script où est exécutée la fonction.

Le mot clé global peut également être spécifié en début de script, à la première utilisation d'une variable, de sorte à indiquer à l'interpréteur PHP que la variable doit être de portée globale. Cet usage du mot clé global est probablement le plus courant.

Les exemples précédents montrent bien qu'il est parfaitement légal de réutiliser un nom de variable, pour des variables déclarées hors et au sein d'une fonction, sans interférence entre les variables de même nom. Cette pratique est toutefois déconseillée, parce qu'elle est source de confusion.

Pour l'instant, nous terminons ce deuxième chapitre et nous verrons dans le prochain, l'usage de Passer par référence contre passer par valeur ainsi que la Sortie forcée d'une fonction et Renvoie de valeurs par des fonctions.


Implémentation d'Ouverture et Fermeture de Session, Mot de Passe

Authentifier les Utilisateurs et personnaliser le site (3ème partie) :

Implémentation d'ouverture de session :

Lorsque des utilisateurs saisissent leurs informations dans le formulaire du script de connexion.php ou login.php (voir figure 4 à cette adresse, en cliquant ici) et qu'ils les renvoient. Ils arrivent sur le script de la page de Bienvenue.php à laquelle que les utilisateurs peuvent cliquer sur le lien du menu "Ajouter un Signet". Ce script permet d'ouvrir une session si l'utilisateur vient de compléter le formulaire de la figure 7, et il affiche tous les sites favoris de l'utilisateur qui vient d'ouvrir la session, en cliquant sur le lien du menu "Voir vos Signets". Ce script est donc le centre de notre application, et il est présenté dans le Listing 9.

Listing 9. - Le fichier member.php - Le script central de l'application :

Vous reconnaissez peut-être la logique de ce script : nous y reprenons certaines idées expliquées dans une de nos leçons précédentes.

Tout d'abord, nous vérifions si l'utilisateur vient de remplir le formulaire, et nous tentons d'ouvrir une session :

if ($username && $password)

//L'utilisateur vient de compléter le formulaire

{

if (login($username, $password))

{

//S'il est dans la base de données, on enregistre son indentificateur.

session_start() ;

$_SESSION['password'] = $_POST['password'];

// Avec la fonction ISSET Si la variable $_POST['valid_user'] existe, alors $valid_user = $_POST['valid_user'] sinon, elle vaut NULL

$valid_user = isset($_POST['valid_user']) ? $_POST['valid_user'] : NULL ;

// Ou avec !EMPTY() Si la variable $_POST['valid_user'] existe et n'est pas vide, alors $valid_user = $_POST['valid_user'] sinon, elle vaut NULL

$valid_user = !empty($_POST['valid_user']) ? $_POST['valid_user'] : NULL;

$valid_user = $username ;

$_POST["valid_user"] ;

}

Pour le reste du programme, voir le Listing 9.

Vous pouvez constater que nous tentons d'ouvrir la session avec une fonction appelée login(). Cette fonction est définie dans la bibliothèque user_auth_fns.php, et nous allons étudier son code dans un instant.

Si l'ouverture de session est réussie, nous enregistrons cette session comme nous le faisions auparavant, en enregistrant le nom de l'utilisateur dans la variable de session $valid_user.

Si tout se passe bien, nous pouvons afficher la page personnelle de l'utilisateur :

do_html_header("") ;

check_valid_user() ;

// Récupère les sites favoris de cet utilisateur.

if ($url_array = get_user_urls($valid_user)) ;

display_user_urls($url_array) ;

// Affiche le menu d'options.

display_user_menu() ;

do_html_footer() ;

Une fois de plus, cette page est créée à l'aide des fonctions de sortie. Vous remarquerez que nous utilisons également plusieurs nouvelles fonctions : check_valid_user() de user_auth_fns.php, get_user_urls() de url_fns.php et display_user_urls() de output_fns.php. La fonction check_valid_user() vérifie si l'utilisateur actuel a ouvert une session enregistrée. Elle n'est pas destinée aux utilisateurs qui viennent d'ouvrir une session, mais à ceux qui sont en plein milieu de leur session. La fonction get_user_urls() récupère les liens d'un utilisateur dans la base de données, et display_user_urls() affiche ces liens dans le navigateur, sous la forme d'un tableau. Nous reviendrons sur check_valid_user() et sur les deux autres fonctions dans un instant, dans la section consacrée à l'enregistrement et à la lecture des liens.

Le script member.php ou add_bms.php termine la page, en affichant un menu avec la fonction display_user_menu().

Un exemple de sortie générée par add_bms.php est présenté à la figure 8.

Comme vous pouvez le constater dans le Listing 9, cette page member.php ou add_bms.php se connecte à la base de données et vérifie si un utilisateur possédant le nom et le mot de passe spécifiés existe bien. Elle renvoie true dans ce cas, et false dans le cas contraire, ou si les informations de l'utilisateur n'ont pas pu être vérifiées.

La fonction check_valid_user() se connecte également de nouveau à la base de données mais, elle se contente de vérifier si l'utilisateur a bien enregistré une session, c'est-à-dire s'il s'est bien loggé sur le site. Cette fonction est présentée dans le Listing 10.

Listing 10. - La fonction check_valid_user() de user_auth_fns.php - Cette fonction vérifie si l'utilisateur possède une session valide :

Si l'utilisateur ne s'est pas loggé, cette fonction lui indique qu'il doit ouvrir une session pour afficher cette page et lui propose un lien vers la page de login.

Fermeture de session :

Vous avez peut-être remarqué qu'il existe un lien "Se Déconnecter" sur le menu de la figure 8. Il s'agit d'un lien vers le script logout.php. Le code de ce script est présenté dans le Listing 11.

Listing 11. - logout.php - Ce script permet de fermer la session d'un utilisateur :

Une fois de plus, ce code peut vous sembler familier. En effet, il reprend le code que nous avions écrit dans la leçon précédente. En cliquant ici.

Modifier les mots de passe :

Si un utilisateur choisit l'option Modifier le Mot de Passe, il obtient le formulaire présenté à la figure 9.

Ce formulaire est généré par le script edit_infos.php. Il s'agit d'un script qui se contente d'utiliser certaines fonctions de la bibliothèque de sortie que nous avions déjà évoqué dans une de nos leçons, c'est pourquoi qu'on va présenter de nouveau son code source, puisqu'il y a eu une certaine modification des mises à jour des informations du fichier edit_infos.php.

Listing 12. - edit_infos.php - Ce script tente de modifier le mot de passe ainsi que certaines informations d'un utilisateur :

Lorsque le formulaire est envoyé, il active le script de connexion.php du Listing 13, puis le désactive ensuite via le message d'avertissement comme suit : "Vos informations ont bien été modifiées. Vous devez vous reconnecter, en vous remerciant !, en cliquant sur le lien "Se connecter". (Voir le Listing 12).

Listing 13. - connexion.php - Ce script permet de se connecter sur le site de l'espace membre :

Ce script vérifie que l'utilisateur s'est bien loggé, mais que nous avions déjà écrit dans le Listing 3 de la leçon précédente, et nous le reportons ici-même, en cliquant ici. Et nous vérifions également que le formulaire du mot de passe ainsi que les autres informations a bien été rempli et nous vérifions à nouveau si les mots de passe s'ils sont bien identiques et qu'ils ont une longueur appropriée. Rien de tout cela n'est très nouveau. Si tout se passe bien, les informations doivent se mettre à jour dans la base de données :

//On modifie les informations de l'utilisateur avec les nouvelles

if(mysql_query('UPDATE membre_utilisateurs SET Nom_Utilisateur = "'.$username.'", Mot_de_Passe="'.$password.'", E_Mail="'.$email.'", Avatar="'.$avatar.'" where id="'.mysql_real_escape_string($_SESSION['userid']).'"'))

{

//Si cela a fonctionné, on n'affiche pas le formulaire

$form = false;

//On supprime les sessions username et userid au cas ou il aurait modifié son Pseudo

unset($_SESSION['username'], $_SESSION['userid']);

Pour la fermeture de l'accolade, voir le Listing 12.

Nous terminons ainsi ce troisième chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation de l'enregistrement et de la lecture des liens.


Opérateurs Arithmétiques

Opérateurs Arithmétiques, Opérateurs de Comparaison, Opérateurs Logiques, Opérateurs Bitwise et Divers Opérateurs (3ème partie) :

OPÉRATEURS :

Les opérateurs sont représentés par des symboles, et sont utilisés pour manipuler des valeurs et des variables, en les soumettant à des opérations. Pour calculer les totaux et la taxe du bon de commande du client de Jean-Pierre, nous devons recourir à des opérateurs.

Nous avons déjà mentionné deux opérateurs : l'opérateur de concaténation de chaînes (.) et l'opérateur d'affectation =. Dans cette section, nous allons passer en revue la liste complète des opérateurs disponibles dans le langage PHP.

En général, les opérateurs peuvent prendre un, deux ou trois arguments, la majorité d'entre eux prenant deux arguments. Par exemple, l'opérateur d'affectation prend deux arguments : l'emplacement de stockage spécifié à la gauche du symbole =, et une expression spécifiée à la droite du signe =. Ces arguments sont appelés "opérandes". Un opérande est un élément auquel s'applique l'opérateur.

OPÉRATEURS ARITHMÉTIQUES :

Avant de continuer notre formulaire de commande de chez Jean-Pierre, nous allons voir les opérateurs arithmétiques du langage PHP sont l'évidence même : ils sont tout simplement les opérateurs mathématiques traditionnels. Le tableau de la figure 5 donne la liste des opérateurs arithmétiques simples.

Tableau de la figure 5 - Opérateurs arithmétiques du langage PHP
Opérateur | Nom | Exemple
+ | Addition | $a + $b
- | Soustraction | $a - $b
* | Multiplication | $a * $b
/ | Division | $a / $b
% | Modulo | $a % $b

Pour chacun de ces opérateurs, nous pouvons stocker le résultat de l'opération, par exemple :

$Resultat = $a + $b ;

L'addition et la soustraction fonctionnent comme nous pouvons nous y attendre. Ces opérateurs conduisent respectivement à l'addition et à la soustraction des valeurs stockées dans les variables $a et $b.

L'opérateur de soustraction (-) s'utilise également comme opérateur unaire (c'est-à-dire qui ne prend qu'un seul opérande) pour spécifier des nombres négatifs, comme dans l'exemple suivant :

$a = -1 ;

Le fonctionnement de la multiplication et de la division est lui aussi le fonctionnement attendu. Notez l'usage du caractère astérisque (*) pour l'opérateur de multiplication, au lieu du symbole classique de multiplication, et l'usage de la barre oblique pour l'opérateur de division, au lieu du symbole classique de la division.

L'opérateur modulo renvoie le reste de la division de la variable $a par la variable $b. Soit le fragment de code suivant :

$a = 47 ;

$b = 10 ;

$Resultat = $a%$b ;

La valeur stockée dans la variable $Resultat est le reste obtenu après division de 47 par 10, c'est-à-dire 7, donc, il reste 7.

Les opérateurs arithmétiques sont généralement appliqués à des entiers ou à des nombres réels (double). Lorsqu'ils sont appliqués à des chaînes, l'interpréteur PHP tente de convertir les chaînes en nombres. Lorsque les chaînes contiennent un "e", ou un "E", PHP les convertit en nombres réels, sinon, il les convertit en nombres entiers. PHP examine si des chiffres forment le début de la chaîne, et, si c'est le cas, les utilise comme valeur numérique. Si ce n'est pas le cas, l'interpréteur PHP convertit la chaîne en la valeur zéro.

OPÉRATEUR DE CHAÎNES :

Nous avons déjà vu l'unique opérateur de chaîne admis par le langage PHP : l'opérateur (.) de concaténation de chaînes. Cet opérateur s'emploie pour accoler deux chaînes l'une à l'autre. Il génère et stocke son résultat à la manière de l'opérateur d'addition.

$a = "<BR> <H1> <b> &nbsp;&nbsp;&nbsp; Les composants Électroniques &nbsp;" ;

$b = "de chez Jean-Pierre !!!" ;

$Resultat = $a . $b ;

echo $Resultat ;

Après l'exécution de ces instructions, la variable $Resultat contient la chaîne de caractères ci-après : "Les composants Électroniques de chez Jean-Pierre !!!".

N.B. : &nbsp; donne un espace pour séparer les caractères, et, pour visualiser l'aperçu, en cliquant ici.

OPÉRATEURS D'AFFECTATION :

Nous avons déjà évoqué l'opérateur d'affectation =. Cet opérateur doit toujours être désigné comme étant l'opérateur d'affectation, et se lit comme "est ajustée sur". Par exemple :

$TotalQty = 0 ;

Se lit comme "$TotalQty est ajustée sur la valeur zéro". Nous reviendrons sur ce point un peu plus loin dans cette leçon, lorsque nous étudierons les opérateurs de comparaison.

Valeurs renvoyées après évaluation d'instructions d'affectation :

Lorsque l'opérateur d'affectation est appliqué, l'interpréteur PHP renvoie une valeur, comme il le fait avec les autres opérateurs. Ainsi, l'exécution de l'expression suivante :

$a + $b ;

Renvoie la valeur obtenue, en ajoutant la variable $a à la variable $b. De la même manière, l'exécution de l'expression suivante :

$a = 0 ;

Renvoie la valeur zéro.

De ce fait, vous pouvez implémenter des calculs tels que :

$b = 8 + ($a = 5) ;

Cette expression produit la valeur 13, affectée à la variable $b. Ce principe est vrai pour toutes les affectations : la valeur d'une instruction d'affectation est la valeur affectée à l'opérande spécifié à la gauche de l'opérateur.

Lors de l'écriture d'une expression arithmétique, vous pouvez employer des parenthèses pour forcer la priorité d'une sous-expression, comme dans la ligne de code donné ci-dessus. Le principe est ici exactement le même qu'en mathématiques.

Opérateurs d'affectation combinés :

En sus de l'opérateur d'affectation, le langage PHP admet tout un ensemble d'opérateurs d'affectation combinés. Chacun de ces opérateurs combinés constitue une solution raccourcie pour effectuer une opération spécifique sur une variable, et pour affecter en retour le résultat à cette variable. Ainsi, l'expression suivante :

$a = += 5 ;

Est équivalente à l'expression :

$a = $a + 5 ;

Il existe des opérateurs d'affectation combinés pour chaque opérateur arithmétique et pour l'opérateur de concaténation de chaîne.

Le tableau de la figure 6 dresse une vue récapitulative de tous les opérateurs d'affectation combinés et de leurs effets.

Tableau de la figure 6 - Opérateurs d'affectation combinés
Opérateur | Exemple | Équivalent à
+ = | $a + = $b | $a = $a + $b
- = | $a - = $b | $a = $a - $b
* = | $a * = $b | $a = $a * $b
/ = | $a / = $b | $a = $a / $b
% = | $a % = $b | $a = $a % $b
. = | $a . = $b | $a = $a . $b

Opérateurs de pré/post-incrémentation et de pré/post-décrémentation :

Les opérateurs de pré/post-incrémentation (++) et de pré/post-décrémentation (--) sont équivalents aux opérateurs + = et - =, à quelques détails près.

Tous les opérateurs d'incrémentation ont deux effets : d'une part, ils incrémentent, d'autre part, ils affectent une valeur. Soit les instructions suivantes :

$a = 4 ;

echo ++$a ;

La seconde instruction comprend l'opérateur de pré-incrémentation, ainsi nommé parce qu'il figure avant l'opérande $a. Lorsque l'interpréteur PHP rencontre cet opérateur, il commence par incrémenter $a par 1, puis il renvoie la valeur ainsi incrémentée.

Dans ce cas précis, $a est incrémentée à la valeur 5, puis la valeur 5 est renvoyée et imprimée. La valeur de l'expression complète est 5 (notez que la valeur réellement stockée dans $a a été modifiée : PHP ne se contente pas de renvoyer simplement $a + 1).

Lorsque l'opérateur (++) figure après l'opérande, il est qualifié d'opérateur de post-incrémentation. L'effet produit est différent. Soit les instructions suivantes :

$a = 4 ;

echo $a++ ;

Dans ce cas précis également, l'interpréteur PHP accomplit le traitement inverse : tout d'abord, il renvoie et imprime la valeur de $a, ensuite, il l'incrémente. La valeur de l'expression complète est dans ce cas 4, c'est-à-dire la valeur qui est imprimée. Toutefois, une fois que l'instruction a été exécutée, $a contient la valeur 5.

L'opérateur de décrémentation (--) a un comportement similaire, si ce n'est que la valeur de l'opérande est décrémentée, et non pas incrémentée.

Opérateur de référence :

L'opérateur de référence & (esperluette) est une nouveauté des versions 4 et 5 de PHP. Il peut être utilisé en conjonction avec l'opérateur d'affectation. Dans une affectation standard d'une variable à une autre, l'interpréteur PHP effectue une copie de la première variable, qu'il stocke quelque part dans la mémoire de l'ordinateur. Par exemple, considérez les instructions suivantes :

$a = 5 ;

$b = $a ;

Ces lignes de code conduisent à la création d'une copie de $a, et au stockage de cette copie dans $b. Par la suite, si la valeur de $a est modifiée, alors, la valeur de $b reste inchangée :

$a = 7 ; // $b vaut toujours 5

L'usage de l'opérateur de référence & permet d'éviter de faire une copie, comme le montre l'exemple suivant :

$a = 5 ;

$b = &$a ;

$a = 7 ; // Les variables $a et $b valent à présent toutes deux 7

OPÉRATEURS DE COMPARAISON :

Les opérateurs de comparaison s'emploient pour comparer deux valeurs entre elles. Les expressions contenant de tels opérateurs renvoient les valeurs logiques true (vrai) ou false (faux), selon le résultat de la comparaison.

Opérateur d'égalité :

L'opérateur d'égalité == (deux signes égale) permet de déterminer si deux valeurs sont égales. Par exemple, nous pourrions utiliser l'expression suivante :

$a == $b ;

Pour tester si les valeurs stockées dans $a et $b sont identiques. L'interpréteur PHP renvoie la valeur true si les valeurs sont égales, et la valeur false si elles sont différentes.

L'opérateur d'égalité se confond facilement avec l'opérateur d'affectation (=). Une telle confusion est d'autant plus dangereuse qu'elle ne provoque pas une erreur, mais conduit seulement à un résultat qui n'est pas celui escompté. En général, les valeurs non nulles sont évaluées comme true, tandis que les valeurs nulles sont évaluées comme false.

Supposons que deux variables soient initialisées de la manière suivante :

$a = 5 ;

$b = 7 ;

S'il est amené à tester l'expression $a = $b, l'interpréteur PHP renvoie la valeur true. Pourquoi ? La valeur de l'expression $a = $b est la valeur affectée à l'opérande qui figure sur la gauche de l'opérateur d'affectation, c'est-à-dire ici 7. Cette valeur étant non nulle, l'expression est évaluée comme true. Si votre intention initiale était de tester l'expression $a == $b (au lieu de $a = $b), qui serait évaluée comme false par l'interprétezur PHP, alors, vous avez introduit une erreur logique dans votre code, qui peut se révéler très difficile à détecter. Vous devez par conséquent vous montrer très prudent lorsque vous avez recours à l'opérateur d'affectation ou à l'opérateur d'égalité, et vérifier systématiquement que vous ne confondez pas à ces deux opérateurs.

Cette erreur logique est très courante, et vous vous y heurterez probablement plusieurs fois au cours de votre carrière de programmeur.

AUTRES OPÉRATEURS DE COMPARAISON :

Le Langage PHP comprend tout un jeu d'opérateurs de comparaison. Ceux-ci sont décrits au tableau de la figure 7.

L'opérateur (===) est une nouveauté également depuis les versions 4 et 5. Il renvoie true uniquement si les deux opérandes sont égaux et de même type.

Tableau de la figure 7 - Opérateurs de comparaison du langage PHP
Opérateur | Nom | Exemple
== | égalité | $a == $b
=== | identique | $a === $b
! = | différent | $a ! = $b
<> | différent | $a <> $b
< | inférieur à | $a < $b
> | supérieur à | $a > $b
< = | inférieur ou égal à | $a < = $b
> = | supérieur ou égal à | $a > = $b

OPÉRATEURS LOGIQUES :

Les opérateurs logiques s'utilisent pour combiner les résultats de conditions logiques. Par exemple, considérons le cas d'une variable $a dont la valeur est comprise entre 0 et 100. Pour vérifier que la valeur de $a est bien située dans cette plage, il nous faudrait tester les conditions $a >= 0 et $a <= 100, en nous servant de l'opérateur AND de la manière suivante :

$a >= 0 && <= 100 ;

Le langage PHP comprend les opérateurs logiques AND (et), OR (ou), XOR (ou exclusif) et NOT.

Le tableau de la figure 8 vous décrit ces différents opérateurs.

Tableau de la figure 8 - Opérateurs logiques du langage PHP
Opérateur | Nom | Exemple | Résultat
! | NOT | ! $b | Renvoie true si $b est faux, et vice versa
&& | NAND | $a && $b | Renvoie true lorsque $a et $b sont tous deux vrais ; sinon, renvoie false
| | | OR | $a | | $b | Renvoie true lorsque soit $a, soit $b est vraie, et lorsque $a et $b sont tous les deux vrais : sinon, renvoie false
and | AND | $a and $b | Identique à &&, mais avec une priorité plus basse
or | OR | $a or $b | Identique à | |, mais avec une priorité plus basse

Les opérateurs AND et OR sont de plus faible priorité que les opérateurs && et ||. Nous reviendrons sur la notion de priorité des opérateurs un peu plus loin de nos leçons.

OPÉRATEURS BITWISE :

Les opérateurs bitwise permettent de traiter les nombres entiers sous la forme de séries de bits utilisées pour les représenter.

Bien que ces opérateurs soient peu utiles dans le contexte de programmes PHP, vous en trouverez une description exhaustive du tableau de la figure 9.

Tableau de la figure 9 - Les opérateurs Bitwise du langage PHP
Opérateur | Nom | Exemple | Résultat
& | AND bitwise | $a & $b | Les bits positionnés à 1 dans $a ET dans $b sont positionnés à 1
| | OR bitwise | $a | $b | Les bits positionnés à 1 dans $a OU dans $b sont positionnés à 1
~ | NOT bitwise | ~ $a | Les bits qui sont positionnés à 1 dans $a sont positionnés à 0, et vice versa
^ | XOR bitwise | $a ^ $b | Les bits positionnés à 1 dans $a OU $b, mais pas dans les deux, sont positionnés à 1
<< | décalage à gauche | $a << $b | Décale $b vers la gauche, de $a bits
>> | décalage à droite | $a >> $b | Décale $b vers la droite, de $a bits

AUTRES OPÉRATEURS :

Outre les opérateurs que nous avions vu jusqu'à présent et décrits jusqu'ici, le langage PHP comprend divers autres opérateurs.

L'opérateur virgule (,) s'emploie pour séparer les arguments d'une fonction, ainsi que les éléments d'une liste.

Les deux opérateurs spéciaux new et - > s'utilisent respectivement pour instantier une classe, et pour accéder aux membres d'une classe. Nous les étudierons en détail au cours de nos leçons.

Les opérateurs de tableau ([ ]) permettent d'accéder aux éléments stockés dans des tableaux. Nous en parlerons au cous de nos leçons que l'on verra par la suite.

Il existe encore trois autres opérateurs, que nous allons brièvement décrire dans les prochaines sous-sections.

Opérateur ternaire :

L'opérateur ternaire (?) : est comparable à l'opérateur ternaire du langage C. Il s'utilise de la manière suivante :

condition ? valeur si vraie ; valeur si fausse

L'opérateur ternaire permet d'écrire une expression qui soit l'équivalent d'une instruction if - else, traitée plus loin dans cette leçon.

En voici un exemple simple d'application ; Jean-Pierre a-t-il bien travaillé à l'école ? :

($note > 50 ? "Admis" : "recalé") ;

Cette expression permet de déterminer si les étudiants sont admis ou recalés à leur examen.

L'opérateur de suppression d'erreur :

L'opérateur de suppression d'erreur @ peut s'utiliser devant toute expression, c'est-à-dire devant tout ce qui génère une valeur, ou contient une valeur. Soit l'instruction suivante :

$a = @ (98/0) ;

En l'absence de l'opérateur @, cette ligne de code génère un message de division par zéro. La présence de l'opérateur @ évite l'impression de ce message.

Si vous faites usage de l'opérateur @, prévoyez du code de gestion des erreurs, pour détecter les erreurs qui se produisent. Si vous avez configuré EasyPHP, en activant le paramètre track_errors, les messages d'erreurs générés sont automatiquement stockés dans la variable globale $php_errormsg.

L'opérateur d'exécution :

L'opérateur d'exécution se compose réellement d'une paire d'opérateurs ` ` . Il ne s'agit pas là d'une paire de guillemets simples (apostrophes), mais de guillemets obliques.

L'interpréteur PHP essaye d'exécuter tout ce qu'il rencontre entre deux guillemets obliques comme une commande à la ligne de commande du serveur. La valeur de l'expression est alors le résultat de l'exécution de la commande.

Par exemple, sous un système d'exploitation de type Unix, vous pouvez utiliser :

$out = `1s - 1a` ;

echo "<pre>" . $out ."</pre>" ;

Ou de la même manière, sur un serveur Windows :

$out = `dir c:` ;

echo "<pre>" . $out . "</pre>" ;

L'exécution de chacun de ces fragments de code produit une liste de dossiers, stockée dans la variable $out. Celle-ci peut ensuite être imprimée dans le navigateur, ou bien traitée de toute autre manière.

Il existe d'autres manières d'exécuter des commandes sur un serveur. Nous étudierons par la suite de nos cours. Pour l'instant, nous allons compléter le formulaire de commande de chez Jean-Pierre.

Fin de ce troixième chapitre, le prochain sera consacré "à l'utilisation des opérateurs afin de calculer les totaux d'un formulaire de commande de chez Jean-Pierre" qui sera la suite de cette leçon".


Utilisation Shuffle() et Chargement de Tableaux à Partir de Fichiers en PHP

Utilisation de la Fonction shuffle(), Chargement de Tableaux à partir de Fichiers, Navigation au sein d'un Tableau, each, current(), reset(), end(), next(), pos() et prev(), count(), sizeof(), etc. (2ème partie) :

Retrier des tableaux :

Dans certaines applications, il apparaît nécessaire de "retrier" des tableaux selon d'autres critères. La fonction shuffle() permet alors de "mélanger" les éléments d'un tableau, c'est-à-dire de les trier de manière aléatoire. La fonction array_reverse() permet quant à elle d'obtenir une copie d'un tableau, dans laquelle tous les éléments ont été triés dans l'ordre inverse.

Utilisation de la fonction shuffle() :

Jean-Pierre aimerait présenter aux visiteurs du site de son entreprise, dans le haut de sa page d'accueil, un petit échantillonnage des articles proposés à la vente. Il aimerait extraire au hasard trois des articles de son catalogue, en proposant un échantillonnage différent à chaque nouvelle visite de ses clients, pour préserver l'intérêt de ces derniers. Un tel affichage mis à jour est facile à implémenter si tous les articles sont stockés dans un même tableau. L'exécution du listing ci-dessous, produit l'affichage de trois images d'articles choisies au hasard, en "mélangeant" le contenu du tableau, puis en affichant les images des trois premiers articles du tableau ainsi mélangé.

<HTML>

<HEAD>

<TITLE> Page d'Accueil de chez Jean-Pierre </TITLE>

</HEAD>

<BODY>

<BR/> <BR/> <BR/>

<font face="Arial" size="5" color="#005500"> <CENTER> <b> Actualisez votre Navigateur pour afficher au hasard les trois articles ou &agrave; son chargement de la page ! </b> </CENTER> </font>

<H2> <CENTER> <BR/> Utilisation de PHP pour g&eacute;n&eacute;rer une page d'accueil dynamique sur le site Web de chez Jean-Pierre. </CENTER> </H2>

<H1> <CENTER> <BR/> Les composants &eacute;lectroniques du site de chez Jean-Pierre ! </CENTER> </H1>

<BR/> <BR/> <BR/>

<TABLE WIDTH = 100%>

<tr>

<?php

$pictures = array ("images/Trois_Leds.jpg", "images/Led.jpg", "images/Trois_Resistances.jpg" ,

"images/Transistor.jpg", "images/Thyristor.gif" ,

"images/Fusibles.jpg", "images/Condensateur.jpg" ,

"images/Resistance_Bobine.jpg", "images/Potentiometre.gif") ;

shuffle ($pictures) ; // Permet de charger une image aléatoire à l'aide de la fonction "shuffle()".

for ($i = 0 ; $i < 3 ; $i ++)

{

echo "<td align = 'center'> <img src = \"" ;

echo $pictures [$i] ;

echo " \" width = '115' height = '115' </td>" ;

}

?>

</tr>

</TABLE>

</BODY>

</HTML>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 10].

Etant donné que le code du listing ci-dessus, opère une sélection aléatoire d'images, il conduit à l'affichage d'une page différente à chaque chargement ou presque (voir figure 5).

Utilisation de la fonction array_reverse() :

La fonction array_reverse() crée un nouveau tableau, dont le contenu est celui du tableau qui est fourni comme argument, mais trié dans l'ordre inverse. Considérons par exemple le cas d'un tableau contenant un décompte de dix à un. Il existe différentes manières de générer un tel tableau.

Nous pouvons utiliser la fonction range(), qui crée une série croissante, puis la fonction rsort pour trier cette série par ordre décroissant. Nous pouvons également créer les éléments du tableau un à un, au moyen d'une boucle for, comme suit :

    $Nombres = array() ;

    for ($i = 10 ; $i > 0 ; $i --)

    array_push ($Nombres, $i) ;

C'est ainsi qu'une boucle for peut procéder par ordre décroissant : il suffit de choisir une valeur initiale suffisamment élevée, et d'utiliser l'opérateur -- (post-décrémentation) pour diminuer le compteur d'une unité à chaque répétition de la boucle.

Le code précédent commence par créer un tableau vide, puis remplit peu à peu ce tableau par le biais de la fonction array_push() implémentée dans la boucle for, et qui ajoute chaque nouvel élément après le contenu existant déjà dans le tableau. Notez que la fonction array_pop() fait pendant à la fonction array_push() : elle supprime un élément à la fin du tableau qui lui est passé comme argument, en renvoyant l'élément supprimé.

Nous pouvons également utiliser la fonction array_reverse() pour trier dans l'ordre inverse, un tableau généré au moyen de la fonction range() :

    $Nombres = range (1, 10) ;

    $Nombres = array_reverse ($Nombres) ;

Notez que la fonction array_reverse() renvoie une copie modifiée du tableau qui lui est passé comme argument. Dans les lignes de code précédentes, toutefois, nous écrasons le tableau d'origine avec la nouvelle copie générée, parce que le tableau d'origine ne nous est plus d'aucune utilité.

Chargement de tableaux à partir de fichiers :

Nous avons vu dans la 2ème leçon, comment stocker les commandes clients dans un fichier, dont chaque ligne se présenterait de la manière suivante :

15 / 04 / 2016, 18 : 30 : 35 | 25 Resistance(s) | 56 Condensateur(s) | 98 Transistor(s) | Poupette DUPOND - 5, rue du Vésinet - 45 LOIRET

En vue du traitement de cette commande, nous pourrions la charger dans un tableau. Le script donné dans le listing ci-dessous permet d'afficher le contenu courant du fichier de commandes.

    <?php

          echo "<BR/> <BR/>" ;

          $Ordres_de_Commandes = file ("Orders/Commandes.txt") ;

          $Nombre_de_Commandes = count ($Ordres_de_Commandes) ;

          if ($Nombre_de_Commandes == 0)

      {

          echo "<p align='CENTER'> <font face='Arial' size='3' color='#FF0000'> <b> Il n'y a pas de commandes en attente. Veuillez revenir plus tard. </b> </font> </p>" ;

      }

          for ($i = 0; $i < $Nombre_de_Commandes ; $i ++)

      {

          echo "<p> <font face='Arial' size='3' color='005500'> <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . $Ordres_de_Commandes [$i] . "</b> </font> </p>" ;

      }

    ?>

Pour visualiser l'aperçu, en cliquant ici. [Exemple 11].

Le résultat obtenu à l'exécution de ce script est presque identique à celui produit par la 2ème leçon, en cliquant ici . Cette fois cependant, la fonction file() est utilisée pour charger l'intégralité du fichier dans un tableau. Chaque ligne du fichier devient alors un élément du tableau généré.

D'autre part, le listing ci-dessus utilise la fonction count() pour déterminer le nombre d'éléments du tableau créé.

Nous pouvons encore affiner cette opération de chargement de fichier, en chargeant chacune des sections des différentes lignes de commande dans des éléments séparés du tableaux, de sorte à pouvoir traiter les sections séparément les unes des autres, ou à les mettre en forme de manière plus attractive. Le listing ci-dessous donne le code correspondant.

<HTML>

<HEAD>

<TITLE> Les Composants &Eacute;lectroniques </TITLE>

</HEAD>

<BODY>

<BR/> <BR/>

<H1> <CENTER> Les Composants &Eacute;lectroniques de chez Jean-Pierre ! </CENTER> </H1>

<H2> <CENTER> Bon de commande ! </CENTER> </H2>

<?php

// Lecture de l'intégralité du fichier. Chaque commande devient un élément du tableau.

$Commandes = file ("test_3.txt") ;

// Comptage du nombre de commandes stockées dans le tableau

$Nombre_de_Commandes = count ($Commandes) ;

if ($Nombre_de_Commandes == 0)

{

echo "<p><font face='Arial' size='3' color='#FF0000'> <CENTER> <b>N&deg; de Commandes en cours. Veuillez r&eacute;essayer plus tard. </b> </CENTER> </font> </p>" ;

}

echo "<CENTER> <TABLE BORDER = 1>\n" ;

echo "<tr><th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Date de Commande </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> R&eacute;sistances </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Condensateurs </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Transistors </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Montant Total </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Pr&eacute;nom </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Nom de Naissance </b> </font> </td>

<th bgcolor = \"#FFC891\"> <font face='Arial' size='3' color='#005500'> <b> Adresse </b> </font> </td>

</tr> </CENTER>" ;

for ($i = 0 ; $i < $Nombre_de_Commandes ; $i ++)

{

// Scission de chaque ligne

$line = explode( "\t", $Commandes [$i] ) ;

// Ne retient que le nombre des articles commandés

$line[1] = intval($line[1]) ;

$line[2] = intval($line[2]) ;

$line[3] = intval($line[3]) ;

// Sortie de chaque commande

echo "<tr><td> <font face='Arial' size='3' color='#000080'> $line[0] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[1] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[2] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[3] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[4] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[5] </td>

<td align = CENTER> <font face='Arial' size='3' color='#000080'> $line[6] </td>

<td align = LEFT> <font face='Arial' size='3' color='#000080'> $line[7] </td>

</tr>" ;

}

echo "</TABLE>" ;

?>

</BODY>

</HTML>

Si vous avez bien suivi nos premières leçons jusqu'à celles-ci, vous devriez comprendre qu'en remplissant le formulaire de chez Jean-Pierre, en cliquant ici , vos données seront sauvegardées et chargées dans un tableau. Pour se rendre compte des enregistrements concernant le tableau via les codes PHP, il suffit de cliquer ici , puis via le fichier texte (Bloc-Notes) qui se charge automatiquement dans le même tableau, en cliquant ici. Si ce dernier que vous voyez une page banche, il suffit d'actualiser votre navigateur afin que vous puissiez voir vos données enregistrées mais, le plus important, c'est celui du tableau que les données ou les informations seront sauvegardées automatiquement.

En résumant, vous avez quatre fichiers comme suit :

Un fichier intitulé "Bon_de_Commande.php", et pour visualiser l'aperçu, en cliquant ici. [Exemple 12].

Un second fichier intitulé "Ordre_de_Commande.php" permettant d'obtenir un récapitulatif de commandes.

Un troisième fichier intitulé "Affiche_les_Commandes.php", en cliquant ici.

Et le dernier fichier dans l'intitulé "test.txt", en cliquant ici , celui-ci permet d'enregistrer les commandes clients puis, de le charger dans un tableau pour la mise en forme des données.

A noter : Nous n'avons pas mis de tests conditionnels concernant les champs du formulaire de commande afin d'en simplifier la programmation mais, vous pouvez complémenter le programme en question. Ce dernier a pour but d'éducatif et de vous familiariser avec le langage PHP (pour rendre les champs obligatoires par exemple).

Le code du Listing ci-dessus de l'exemple [12], charge l'intégralité du fichier dans un tableau. Contrairement toutefois à l'exemple [11], c'est ici que la fonction explode() qui est employée pour scinder chaque ligne, pour mettre ensuite, en forme la sortie avant son impression sur le moniteur ou sur une imprimante.

Le résultat obtenu à l'exécution du Listing ci-dessus de l'exemple [12] est montré à la figure 6.

La fonction explode() s'utilise avec le prototype suivant :

    array explode (string séparateur, string chaîne)

Au cours de nos leçons précédentes, nous avons utilisé le caractère de tabulation, en guise de délimiteur lors du stockage de ces données. Par conséquent, l'appel de la fonction explode() doit ici être implémenté de la manière suivante :

    explode("\t", $Commandes[$i])

Cette instruction a pour effet de scinder, en plusieurs parties la chaîne passée comme argument. Chaque caractère de tabulation devient une séparation entre deux éléments. Par exemple, la chaîne suivante :

    18 / 04 / 2016, 00 : 27 : 13 \t 1 Resistance(s)\t 2 Condensateur(s)\t 3 Transistor(s)\t 27.60 euros\t Jacques\t DURAND\t 2, Rue de la violette - Escalier, 5 - 29000 AUDIERNE

est scindée en différentes parties, qui sont les suivantes :

    "18 / 04 / 2016, 00 : 27 : 13 ", "1 Resistance(s)", "2 Condensateur(s)", "3 Transistor(s)", "27.60 euros", "Jacques," "DURAND," et "2, Rue de la violette - Escalier, 5 - 29000 AUDIERNE".

Dans le même code du Listing ci-dessus de l'exemple [12], le traitement auquel sont soumises les données extraites du fichier de commande est minimal. Seules les quantités d'articles sont imprimées en sortie sur chaque ligne, puisqu'une ligne d'en-tête indique la signification des nombres affichés.

Différentes possibilités sont offertes pour extraire des nombres contenus dans des chaînes. Dans le Listing ci-dessus de l'exemple [12], nous avons utilisé la fonction intval(), qui convertit une chaîne (string), en un nombre entier (integer). Cette conversion est effectuée de manière raisonnablement intelligente, puisque les parties qui ne peuvent être converties, en nombre entier sont ignorées. Nous étudierons diverses autres méthodes de traitement des chaînes au cours des prochaines leçons.

Autres manipulations de tableaux :

Nous avons vu jusqu'ici qu'une moitié (environ) des fonctions de traitement de tableaux offertes par PHP. Parmi les autres fonctions de manipulation de tableaux, nombre ne sont utiles que de manière occasionnelle.

Navigation au sein d'un tableau ; each(), current(), reset(), end(), next(), pos(), et prev() :

Nous avons vu plus haut que chaque tableau comprend un pointeur interne dirigé sur l'élément courant du tableau. Nous avons déjà fait usage de manière indirecte de ce pointeur, lors de la mise en oeuvre de la fonction each(). Il est également possible d'utiliser et de manipuler directement ce pointeur

A la création d'un nouveau tableau, le pointeur est initialisé de sorte à pointer sur le premier élément du tableau. Pour connaître l'élément courant dans un tableau, il suffit d'invoquer la fonction current(), en passant à celle-ci le nom du tableau comme argument.

Les fonctions next() et each() permettent toutes deux de faire avancer le pointeur d'un élément. La fonction each() renvoie l'élément courant avant de déplacer le pointeur, tandis que la fonction next() fait avancer le pointeur, puis renvoie seulement ensuite le nouvel élément courant.

Comme nous l'avons déjà mentionné, la fonction reset() fait reculer le pointeur sur le premier élément du tableau. De la même manière, la fonction end() déplace le pointeur sur le dernier élément du tableau qui lui est fourni comme argument. Les fonctions reset() et end renvoient respectivement le premier et le dernier élément du tableau qui leur est passé comme paramètre.

Pour parcourir un tableau en sens inverse, vous pouvez employer les fonctions end() et prev(). La fonction prev() est l'opposé de la fonction next() : elle fait reculer le pointeur d'un élément, puis renvoie le nouvel élément courant.

Par exemple, le code qui suit produit l'affichage d'un tableau dans l'ordre inverse :

    $valeur = end ($tableau) ;

    while($valeur)

    {

    echo "$valeur<br>" ;

    $valeur = prev ($tableau) ;

    }

Si la variable $tableau avait été déclarée de la manière suivante :

    $tableau = array (1, 2, 3) ;

Alors le résultat de l'exécution du code précédent serait :

    3

    2

    1

En utilisant les fonctions each(), current(), reset(), end(), next(), pos() et prev(), vous pouvez implémenter votre propre mode de navigation au sein d'un tableau, dans l'ordre qui vous convient.

Application d'une fonction donnée à chaque élément d'un tableau ; array_walk() :

Il est parfois nécessaire de soumettre chaque élément d'un tableau à une même manipulation. La fonction array_walk() apparaît alors très pratique.

La fonction array_walk() s'utilise avec le prototype suivant :

    int array_walk (array tableau, string fonction, [données_utilisateur])

Tout comme la fonction usort(), array_walk() requiert comme deuxième argument une fonction définie par l'utilisateur.

La fonction array_walk() prend trois paramètres. Le premier, tableau, est le tableau dont le contenu doit être traité. Le second, fonction, est le nom de la fonction définie par l'utilisateur, et qui sera appliquée à chaque élément du tableau. Le troisième paramètre, données_utilisateur, est optionnel. S'il est spécifié, il est passé comme argument à la fonction définie par l'utilisateur. Nous allons voir un peu plus loin, un exemple de mise en oeuvre de la fonction array_walk().

Il pourrait, par exemple, se révéler très pratique d'attribuer à chaque élément d'un tableau une fonction qui applique une mise en forme particulière.

Le code qui suit affiche chaque élément sur une nouvelle ligne, invoquant la fonction définie par l'utilisateur MonImprime pour chaque élément du tableau $Valeur :

    $Valeur = array ("Jean-Pierre", "Alain", "Paulette", "Daniel", "Patricia") ;

    function MonImprime($Valeur)

    {

    echo "$Valeur <BR>" ;

    }

    array_walk($Valeur, "MonImprime") ;

Ce qui donne comme résultat ci-après :

Jean-Pierre

Alain

Paulette

Daniel

Patricia

Pour chaque élément du tableau traité, array_walk() prend la clé et la valeur stockée dans le tableau, ainsi que la valeur spécifiée comme paramètre données_utilisateur, puis invoque la fonction que vous avez vous-même écrite de la manière suivante :

    VotreFonction (valeur, clé, données_utilisateur)

Dans la plupart des cas, l'argument données_utilisateur est inutile. Il est toutefois parfois nécessaire, lorsque la fonction que vous avez définie requiert un paramètre.

Occasionnellement, la clé de chaque élément est tout autant nécessaire à la manipulation effectuée que la valeur de l'élément. Ce n'est toutefois pas toujours le cas, comme avec MonImprime(), et la fonction définie par l'utilisateur peut alors ignorer la clé et le paramètre données_utilisateur qui lui sont passés par la fonction array_walk().

Considérons à présent un exemple un peu plus complexe : nous allons écrire une fonction qui modifie les valeurs d'un tableau, et requiert un paramètre. Notez que, dans ce cas, bien que nous ne soyons pas intéressé par la clé, nous devons la spécifier dans la fonction à définir pour pouvoir passer le troisième paramètre.

    $value = array (6) ;

    function MyMultiply (&$value, $key, factor)

    {

        $value *= $factor ;

    }

    array_walk ($value, "MyMultiply", 3) ;

    print_r ($value) ;

La fonction MyMultiply() ainsi défini multiplie chaque élément du tableau par le facteur passé comment argument. Dans le cardre d'une mise en oeuvre de cette fonction par la fonction array_walk(), le facteur de multiplication est spécifié via le troisième argument de array_walk(). Pour que notre fonction MyMultiply récupère ce facteur, il est impératif de la définir avec trois arguments : une valeur d'élément de tableau ($value), une clé d'élément de tableau ($key), et le facteur de multiplication ($factor). Dans ce cas, toutefois, la fonction MyMultiply() ignore la clé qui est passée comme deuxième argument.

Un point subtil mérite votre attention : la manière dont $value est passée à la fonction MyMultiply(). L'esperluette (&) insérée avant le nom de la variable dans la définition de MyMultiply() indique à l'interpréteur PHP que $value doit être passée par référence. Passer une variable par référence permet que la fonction puisse modifier le contenu du tableau.

Cette manière de passer les variables aux fonctions seront étudiées, en détail dans les prochaines leçons. Si cette notion vous est étrangère, il vous suffit pour l'heure de savoir qu'une esperluette doit être placée avant le nom d'une variable pour que la variable soit passée par référence.

Comptage des éléments d'un tableau ; count(), sizeof(), et array_count_values() :

Dans un des exemples précédents, nous avons employé la fonction count() pour déterminer le nombre des éléments d'un tableau stockant des commandes clients. La fonction sizeof() répond exactement au même objectif que la fonction count(). sizeof() et count() renvoient toutes deux le nombre des éléments du tableau qui leur est passé comme argument. Ces fonctions renvoient la valeur 1 lorsqu'elles sont appliquées à une variable scalaire normale, et 0 lorsqu'un tableau vide ou une variable non définie leur sont passés comme argument.

La fonction array_count_values() est plus complexe : elle détermine le nombre d'occurrences de chaque valeur "unique" dans le tableau qui lui est passé comme argument (et donc la "cardinalité" du tableau). Cette fonction renvoie un tableau associatif contenant une table de fréquences. Le tableau renvoyé par array_count_values() contient comme clés toutes les valeurs uniques du tableau passé à array_count_values comme argument ($tableau), et comme valeurs le nombre d'occurrences des clés correspondantes dans $tableau.

Ainsi, le code suivant crée un tableau appelé $Tableau.

    $array = array (4, 5, 1, 2, 3, 1, 2, 1) ;

    $Tableau = array_count_values ($array) ;

    print_r ($Tableau) ;

Sont contenu est le suivant :

Clé | Valeur
4 | 1
5 | 1
1 | 3
2 | 2
3 | 1

L'exécution de ce code produit le résultat suivant :

    Array ( [4] => 1 [5] => 1 [1] => 3 [2] => 2 [3] => 1 )

Dans ce cas précis, le tableau renvoyé par array_count_values() nous informe que le tableau $array contient une seule fois les valeurs 4, 5 et deux fois les valeurs 3, quatre fois la valeur 1, et deux fois la valeur 2.

Conversion de tableaux en variables scalaires ; extract() :

Un tableau associatif contenant des paires clé/valeur peut être transformé, en un ensemble de variables scalaires au moyen de la fonction extract(). Le prototype de la fonction extract() est le suivant :

    extract (array var_array [, int type_extract] [, string préfixe]) ;

La fonction extract() génère des variables scalaires à partir du tableau qui lui est passé comme argument, en utilisant les clés comme noms de variables, et les valeurs des éléments comme valeurs de variables.

Voici un exemple simple d'utilisation de la fonction extract() :

    $array = array ("key1" => "Valeur_1", "key2" => "Valeur_2", "key3" => "Valeur_3") ;

    extract ($array) ;

    echo "$key1 $key2 $key3" ;

L'exécution de ce code produit le résultat suivant :

    Valeur_1 Valeur_2 Valeur_3

Le tableau $array contient trois éléments dont les clés sont key1, key2 et key3. La fonction extract() appliquée à la variable $array conduit à la création des trois variables scalaires $key1, $key2 et $key3. Vous pouvez constater, dans le résultat obtenu, que les valeurs de $key1, $key2 et $key3 sont respectivement "Valeur_1", "Valeur_2", et "Valeur_3". Ces valeurs proviennent du tableau d'origine $array.

La fonction extract() prend deux arguments optionnels : type_extract, et préfixe. Le paramètre type_extract indique à la fonction extract() la manière dont doivent être gérées les collisions, c'est-à-dire les situations où il existe déjà une variable portant le même nom. Le comportement par défaut de extract() consiste à écraser la variable existante. Le tableau de la figure 7 décrit les quatre valeurs aurorisées comme argument type_extract.

Fig. 7. - Valeurs permises pour l'argument "type_extract" de la fonction extract().
Type | Signification
EXTR_OVERWRITE | Écrase la variable existante en cas de collision.
EXTR_SKIP | Saute l'élément en cas de collision.
EXTR_PREFIX_SAME | Crée une variable dénommée $prefix_key en cas de collision. Le paramètre préfixe doit alors être spécifié.
EXTR_PREFIX_ALL | Préfixe tous les noms de variable avec la valeur spécifiée dans le paramètre préfixe. Le paramètre préfixe doit alors être spécifié.

Les deux valeurs les plus couramment utilisées pour l'argument type_extract sont la valeur par défaut (EXTR_OVERWRITE) et EXTR_PREFIX_ALL. Les deux autres valeurs autorisées sont utiles de manière occasionnelle, lorsqu'une collision particulière est attendue, et que vous voulez "sauter" ou préfixer la clé posant problème. Le fragment de code qui suit illustre l'utilisation de la valeur EXTR_PREFIX_ALL. Observez la manière dont sont formés les noms des variables créées : préfixe-caractère de soulignement-nom de la clé.

    $array = array ("key1" => "Valeur_1", "key2" => "Valeur_2", "key3" => "Valeur_3") ;

    extract ($array, EXTR_PREFIX_ALL, "MomPrefixe") ;

    echo "$MomPrefixe_key1 $MomPrefixe_key2 $MomPrefixe_key3" ;

Là encore, le résultat obtenu à l'exécution des lignes de codes précédents est Valeur_1, Valeur_2, Valeur_3.

Notez que pour la fonction extract() puisse extraire un élément, il faut que la clé de l'élément soit un nom de variable valide : les clés dont les noms commencent par des chiffres, ou qui contiennent des espaces, ne peuvent être extraites.

Cette troisième leçon décrite certaines fonctions de manipulation de tableau qui apparaissent les plus utiles. Certaines fonctions également n'y sont volontairement pas abordées. Nous vous invitons à rechercher sur le Net.

Pour l'instant, nous terminons cette troisième leçon et nous verrons dans la prochaine, les manipulations de chaînes et d'expressions régulières, etc. ...


Calcul des Totaux d'un Formulaire de Commande

Utilisation des Opérateurs, Calcul des Totaux d'un Formulaire. (4ème partie) :

UTILISATION DES OPÉRATEURS - CALCUL DES TOTAUX D'UN FORMULAIRE DE COMMANDE :

Maintenant que nous avions expliqué dans les leçons précédentes, et que vous connaissez les opérateurs du langage PHP, nous allons pouvoir calculer les totaux et la taxe (TTC) du formulaire de commande de chez Jean-Pierre.

Pour cela, ajoutez le code suivant en-dessous de la variable "$TransisQty" de votre script PHP :

echo " <BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Prix des articles &agrave; l'unit&eacute;, hors taxe : <BR/> " ;

echo " <BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - R&eacute;sistance : 2 euros <BR/> " ;

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Condensateur : 3 euros <BR/> " ;

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Transistor : 5 euros </b> </font> " ;

Maintenant, ajoutez le code suivant en-dessous de la "define ("TRANSISPRIX", 5) ;" de votre script PHP :

$TotalQty = $ResisQty + $CondosQty + $TransisQty ;

$Montant_Total = ($ResisQty * RESISPRIX) + ($CondosQty * CONDOSPRIX) + ($TransisQty * TRANSISPRIX) ;

$Montant_Total = number_format ($Montant_Total, 2) ;

echo " <BR> <BR> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Articles Command&eacute;s : </font> <font color=005500> " . $TotalQty . " Articles " . " </b> </font> <BR/> <BR/> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sous-Total HT : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> <BR/> " ;

$Taux_Imposition_TTC = 0.20 ; // La Taxe locale est de 20%

$Montant_Total = $Montant_Total * (1 + $Taux_Imposition_TTC) ;

$Montant_Total = Number_format($Montant_Total, 2) ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total TTC (20%) : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> <BR/> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total facture : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> " ;

En fin de cette leçon, nous vous évoquerons les deux fichiers principaux concernant le code HTML y compris le code PHP complet, afin de ne pas interpréter une confusion pour celles ou pour ceux qui n'ont pas bien suivi nos débuts de nos leçons.

Pour l'instant, remplissez les champs du formulaire d'un bon de commande de chez Jean-Pierre, ensuite, cliquez sur le bouton "Commande envoyée". Vous devriez obtenir le résultat complet montré à la figure 10.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 5].

Comme vous pouvez le constater, ce morceau de code fait intervenir plusieurs opérateurs. Les opérateurs d'addition (+) et de multiplication (*) sont utilisés pour calculer les montants, tandis que l'opérateur de concaténation de chaînes (.) est utilisé pour mettre en forme la sortie des données dans la fenêtre du navigateur.

D'autre part, la fonction number_format() est mise en oeuvre pour mettre en forme les totaux sous forme de chaînes à deux décimales. Cette fonction appartient à la bibliothèque de Mathématiques de PHP.

Si vous examinez attentivement les calculs effectués dans le dernier fragment de code ajouté à votre script, vous vous interrogerez peut-être sur l'ordre dans lequel ces calculs sont effectués. Par exemple, considérez l'instruction suivante :

$Montant_Total = ($ResisQty * RESISPRIX) + ($CondosQty * CONDOSPRIX) + ($TransisQty * TRANSISPRIX) ;

Le total obtenu semble correct (voir figure 10), mais pourquoi les multiplications ont-elles été effectuées avant les additions ? La réponse à cette question réside dans la notion de priorité des opérateurs, c'est-à-dire dans l'ordre dans lequel l'interpréteur PHP évalue les opérateurs.

Nous allons maintenant évoquer les codes HTML et PHP des deux fichiers en question :

Premier fichier intitulé : "Bon_de_Commande.php", concernant uniquement le formulaire HTML.

<HTML>

<HEAD>

<TITLE> Bon de Commande </TITLE>

</HEAD>

<BODY>

<FORM ACTION = "Ordre_de_Commande.php" METHOD ="POST"> <BR>

<TABLE BORDER = "0">

<tr bgcolor = "#cccccc">

<td width = "150"> <font face = "Arial" size = "3" color = "#000000"> <b> Articles </b> </font> </td>

<td width = "20"> <font face = "Arial" size = "3" color = "#000000"> <b> Quantit&eacute;s </b> </font> </td>

</tr>

<tr>

<td> <font face = "Arial" size = "3" color = "#000000"> R&eacute;sistances </font> </td>

<td align = "center"> <input type = "text" name = "ResisQty" size = "3" maxlength = "2"> </td>

</tr>

<tr>

<td> <font face = "Arial" size = "3" color = "#000000"> Condensateurs </font> </td>

<td align = "center"> <input type = "text" name = "CondosQty" size = "3" maxlength = "2"> </td>

</tr>

<tr>

<td> <font face = "Arial" size = "3" color = "#000000"> Transistors </font> </td>

<td align = "center"> <input type = "text" name = "TransisQty" size = "3" maxlength = "2"> </td>

</tr>

<tr>

<td colspan = "2" align = "center"> <BR> <input type = "submit" value = "Commande envoy&eacute;e"> </td>

</tr>

</TABLE>

</FORM>

</BODY>

</HTML>

Nous allons maintenant évoquer uniquement que le fichier fournissant les totaux des résultats dont vous trouverez le code en PHP dans l'intitulé : "Ordre_de_Commande.php" (deuxième fichier).

<HTML>

<HEAD>

<TITLE> Les Composants &Eacute;lectroniques de chez Jean-Pierre. </TITLE>

</HEAD>

<BODY>

<BR> <H1> &nbsp; <font face = "Arial"> Les Composants &Eacute;lectroniques de chez Jean-Pierre. </H1>

<H2> &nbsp; Trier les R&eacute;sultats. </font> </H2>

<?php

echo " &nbsp;&nbsp;&nbsp;&nbsp; <b> <font face = Arial size = 3 > Commande trait&eacute;e au : </b> " ;

echo date ("d / m / Y, H : i : s") ;

echo " <p> &nbsp;&nbsp;&nbsp;&nbsp; <b> Votre commande est la suivante : </b> " ;

echo " <BR> <BR> " ;

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " . $ResisQty = $_POST ["ResisQty"] . " <b> &nbsp;&nbsp; R&eacute;sistance(s) </b> <BR/> ";

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " . $CondosQty = $_POST ["CondosQty"] . " <b> &nbsp;&nbsp; Condensateur(s) </b> <BR/> ";

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " . $TransisQty = $_POST ["TransisQty"] . " <b> &nbsp;&nbsp; Transistor(s) <BR/> ";

echo " <BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Prix des articles &agrave; l'unit&eacute;, hors taxe : <BR/>" ;

echo " <BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - R&eacute;sistance : 2 euros <BR/> " ;

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Condensateur : 3 euros <BR/>" ;

echo " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Transistor : 5 euros </b> </font> " ;

$TotalQty = 0 ; // Initialisation d'une variable $TotalQty

$Montant_Total = 0.00 ; // Initialisation d'une variable $Montant_Total

define ("RESISPRIX", 2) ; // Constantes d&eacute;finissant les Prix

define ("CONDOSPRIX", 3) ; // Constantes d&eacute;finissant les Prix

define ("TRANSISPRIX", 5) ; // Constantes d&eacute;finissant les Prix

$TotalQty = $ResisQty + $CondosQty + $TransisQty ;

$Montant_Total = ($ResisQty * RESISPRIX) + ($CondosQty * CONDOSPRIX) + ($TransisQty * TRANSISPRIX) ;

$Montant_Total = number_format ($Montant_Total, 2) ;

echo " <BR> <BR> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Articles Command&eacute;s : </font> <font color=005500> " . $TotalQty . " Articles " . " </b> </font> <BR/> <BR/> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sous-Total HT : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> <BR/> " ;

$Taux_Imposition_TTC = 0.20 ; // La Taxe locale est de 20%

$Montant_Total = $Montant_Total * (1 + $Taux_Imposition_TTC) ;

$Montant_Total = Number_format($Montant_Total, 2) ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total TTC (20%) : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> <BR/> " ;

echo " <font face=Arial size=3 color=800000> <b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total facture : </font> <font color=005500> " . $Montant_Total . " euros " . " </b> </font> <BR/> " ;

?>

</BODY>

</HTML>

Fin de ce quatrième chapitre, le prochain sera consacré "aux priorités et associativité des opérateurs, ordre d'évaluation des expressions, fonctions de variables, Prise de décision avec des structures conditionnelles, blocs de code, Instructions else, elseif, switch, ainsi que les Structures de répétition, Boucles while" qui sera la suite de cette leçon".


Localisation de Sous-Chaînes dans des Chaînes

Localisation de Sous-Chaînes dans des Chaînes, strstr(), strchr(), strrchr(), stristr(), strpos(), strrpos(), str_replace, substr_replace(), Introduction aux Expressions Régulières (2ème partie) :

Localisation et remplacement de sous-chaînes au moyen de fonctions de traitement de chaîne :

Il arrive fréquemment qu'il faille rechercher une sous-chaîne particulière dans une chaîne plus longue. Etablir de type de correspondance partielle est souvent plus utile qu'un simple test d'égalité.

Dans notre exemple de formulaire de courrier électronique, nous devons déterminer si certains mots clés sont contenus dans le message transmis par le client, pour en déduire le service vers lequel doit être dirigé le message. Par exemple, nous pourrions décider de transmettre au service de vente au détail tous les messages relatifs aux différentes boutiques de chez Jean-Pierre. Nous pourrions alors classer dans cette catégorie de message tous les e-mails contenant le mot "boutique".

Pour opérer cette sélection, nous pourrions utiliser explode() ou strtok() pour identifier les différents mots composant chaque message reçu, en comparant ensuite ces mots à notre critère de sélection (par exemple, le mot "boutique") au moyen de l'opérateur d'égalité ou de la fonction strcmp().

PHP nous offre toutefois la possibilité d'aboutir au même résultat via un simple appel d'une des fonctions de comparaison de chaînes ou d'expressions régulières. Ces fonctions sont destinées à la localisation d'un motif donné dans une chaîne de caractères. Nous allons à présent passer, en revue chacun de ces jeux de fonctions disponibles.

Localisation de sous-chaînes dans des chaînes ; strstr(), strchr(), strrchr(), stristr() :

Pour localiser une chaîne au sein d'une autre chaîne, vous pouvez utiliser l'une ou l'autre des fonctions strstr(), strchr(), strrchr(), ou stristr().

La fonction strstr() est la plus générique, et peut être utilisée pour déterminer s'il existe une correspondance entre une sous-chaîne ou un caractère et une chaîne plus longue. Notez qu'en programmation PHP, la fonction strchr() est identique à la fonction strstr(), bien que son nom suggère qu'elle sert à localiser un caractère au sein d'une chaîne (ce qui est bien le cas en programmation C). En réalité, en PHP, la fonction strchr() permet tout autant de localiser un caractère qu'une chaîne de caractères au sein d'une autre chaîne.

Le prototype de la fonction strstr() est le suivant :

    string strstr (string botte_de_paille, string aiguille) ;

La fonction strstr recherche dans la botte_de_paille qui lui est passée comme premier argument s'il existe l'aiguille qui lui est fournie comme deuxième argument. Lorsque strstr() établit qu'il existe une correspondance exacte entre l'aiguille et la botte_de_paille, elle renvoie la part de la botte_de_paille à partir de l'aiguille localisée. Dans le cas contraire, strstr() renvoie la valeur false. Lorsque plusieurs occurrences de la sous-chaîne recherchée sont détectées, strstr() renvoie la part de la chaîne qui commence à la première occurrence de l'aiguille.

Par exemple, dans le cadre de notre application modèle, nous pouvons choisir le destinataire vers lequel un message reçu doit être dirigé, en utilisant le code suivant :

    $Votre_Adresse_Mail = "responsable_informatique_Jean_Pierre@orange.fr" ; // La valeur par défaut

    // Modifie $Votre_Adresse_Mail si le critère de sélection est satisfait

    $Retour_Information = " " ;

    if (strstr($Retour_Information, "boutique"))

    $Votre_Adresse_Mail = "responsable_entrepot@orange.fr" ;

    elseif (strstr($Retour_Information, "livraison"))

    $Votre_Adresse_Mail = "responsable_livraison.Jean@orange.fr" ;

    elseif (strstr($Retour_Information, "facture"))

    $Votre_Adresse_Mail = "responsable_comptabilité@orange.fr" ;

Ce code examine si le message contient certains mots clés, et transmet le message à la personne appropriée. Par exemple, si le message d'un client contient la phrase suivante : "Je n'ai toujours pas reçu la livraison de ma dernière commande", la chaîne livraison sera détectée, et le message sera transmis au responsable_livraison.Jean@orange.fr.

Il existe deux variantes de la fonction strstr(). La première variante, stristr(), est presque identique à strstr(), si ce n'est qu'elle n'est pas sensible à la casse. Elle serait très utile dans l'exemple considéré ici, puisque les données saisies par le client peuvent tout autant contenir des majuscules que des minuscules.

La deuxième variante de la fonction strstr() est strrchr(), qui elle aussi quasi identique à strstr(), excepté qu'elle renvoie la botte_de_paille à partir de la dernière occurrence de l'aiguille.

Détermination de la position d'une sous-chaîne dans une chaîne ; strpos(), et strrpos() :

Les fonctions strpos() et strrpos() opèrent de manière comparable à strstr(), si ce n'est que, au lieu de renvoyer une sous-chaîne, elles renvoient la position numérique de l'aiguille dans la botte_de_paille.

Le prototype de la fonction strpos() est le suivant :

    int strpos (string botte_de_paille, string aiguille, int [offset]) ;

Le nombre entier renvoyé par cette fonction donne la position de la première occurrence de l'aiguille au sein de la botte_de_paille. Le premier caractère occupe la position 0, comme c'est généralement le cas.

Par exemple, le code qui suit imprime la valeur 4 dans la fenêtre du navigateur que si vous tapez le caractère "v" :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Dans ce cas, l'aiguille n'est constituée que d'un seul caractère, mais pourrait être une chaîne de n'importe quelle longueur.

Le paramètre optionnel offset s'emploie pour spécifier une position au sein de la botte_de_paille, à partir de laquelle la recherche doit être entreprise. Par exemple, la ligne de code qui suit :

    $Position = "Bienvenue dans la boutique de chez Jean-Pierre !" ;

    $Test_chaine = "$Position" ;

    @$trouve_moi = $_POST ["recherche"] ;

    @$Position = strpos ($Test_chaine, $trouve_moi, 5 ) ;

ou encore :     echo strpos ($Test_chaine, "v", 5) ;

Conduirait à l'impression de la valeur nulle dans le navigateur, parce que l'interpréteur PHP commencerait la recherche à partir du caractère situé à la position 5, et ne considérerait par conséquent pas le caractère "v" situé à la position 4, donc, la valeur sera nulle puisqu'il n'y a pas d'autres caractères "v" dans la chaîne ci-dessus.

La fonction strrpos() est quasi identique à la fonction strpos(), si ce n'est qu'elle renvoie la position de la dernière occurrence de l'aiguille dans la botte_de_paille. De plus, contrairement à strpos(), la fonction strrpos() ne peut rechercher que des "aiguilles" à un seul caractère. Ainsi, si vous spécifiez une chaîne, en guise d'argument aiguille, strrpo() ne prendra en compte que le premier caractère de cette chaîne.

Lorsque les fonctions strpos() et strrpos() ne localisent aucune occurrence de l'aiguille dans la botte_de_paille, elles renvoient la valeur false. Ce comportement peut se révéler problèmatique, dans la mesure où false est équivalent à 0 dans un langage faiblement typé tel que PHP, et que 0 désigne également la position du premier caractère dans une chaîne.

Vous pouvez éviter toute confusion, en vous servant de l'opérateur === pour tester les valeurs renvoyées, comme suit ; et nous évoquons une partie du code qui se trouve déjà ci-dessus dans le TEXTAREA :

    <?php

    $Position = "Bienvenue dans la boutique de chez Jean-Pierre !" ;

    $Test_chaine = "$Position" ;

    @$trouve_moi = $_POST ["recherche"] ;

    @$Position = strpos ($Test_chaine, $trouve_moi ) ;

    // Notez l'utilisation de === (identit&eacute;). Un simple == (&eacute;galit&eacute;) ne donnerait pas le r&eacute;sultat escompt&eacute ;

    // car la lettre 'B' est à la position 0 (la premi&egrave;re).

    echo "<BR/> <BR/>" ;

    if ($Position === false)

    {

        echo "<font face = 'Arial' size = '3' color = '#000000'><b>&nbsp;&nbsp;&nbsp;&nbsp;La sous-cha&icirc;ne <font color = '#FF0000'> ''$trouve_moi'' </font> n'a pas &eacute;t&eacute; trouv&eacute;e dans la cha&icirc;ne</font></b> <font face = 'Arial' size = '3' color = '#800000'><b> : ''$Test_chaine'' </b> </font>" ;

    }

    else

    {

        echo "<font face = 'Arial' size = '3' color = '#000000'><b>&nbsp;&nbsp;&nbsp;&nbsp;La sous-cha&icirc;ne <font color = '#FF0000'> ''$trouve_moi'' </font> a &eacute;t&eacute; trouv&eacute;e dans la cha&icirc;ne : <font color = '#800000'> ''$Test_chaine'' </b> </font>" ;

           echo "<b> Se trouve &agrave; la position <font color = '#FF0000'> $Position </font> </b>" ;

    }

    ?>

Attention : le code complet se trouve dans le TEXTAREA ci-dessus.

Notez que ce code ne fonctionne qu'avec la version 4 ou ultérieure de PHP. Avec les versions précédentes, vous pouvez détecter si la valeur renvoyée est la valeur false, en testant si la valeur renvoyée est une chaîne.

Substitution de sous-chaînes ; str_replace() et substr_replace() :

La fonctionnalité de recherche/remplacement peut se révéler extrêmement utile pour traiter les chaînes. Elle permet de personnaliser les documents générés par PHP (par exemple, une procédure de recherche/remplacement peut être mise en oeuvre pour remplacer <<name>> par un nom de personne, et <<adresse>> par l'adresse de la personne considérée). Elle permet également d'exercer une censure sur des termes particuliers, par exemple, dans le contexte d'une application de forum de discussion, voire d'une application de formulaire "intelligent".

Là encore, le langage PHP offre un jeu de fonctions spécifiques pour le traitement des chaînes ou des expressions régulières.

str_replace() est la fonction de traitement de chaîne la plus utilisée pour le remplacement. Son prototype est le suivant :

    string str_replace (string aiguille, string nouvelle_aiguille, string botte_de_paille) ;

La fonction str_replace() remplace dans la chaîne botte_de_paille toutes les instances de la sous-chaîne aiguille par la sous-chaîne nouvelle_aiguille.

Par exemple, dans le cadre de notre formulaire de courrier électronique, les clients pourraient glisser des termes injurieux dans leurs messages. Nous pourrions, en tant que programmeurs, éviter aux divers services de l'entreprise de chez Jean-Pierre d'être importunés par de tels messages par une ligne de code du type :

    $Retour_Information = str_replace (De_mauvais_goût, "%!@*", $Retour_Information) ;

La fonction substr_replace() s'utilise pour rechercher et remplacer une sous-chaîne particulière dans une chaîne. Son prototype est le suivant :

    string substr_replace (string chaîne, string remplacement, int début, int [longueur]) ;

Cette fonction remplace une certaine partie de la chaîne chaîne par la chaîne remplacement. Les valeurs des arguments début et longueur définissent la partie à remplacer.

L'argument début spécifie la position dans la chaîne chaîne à partir de laquelle doit intervenir le remplacement. Si la valeur contenue dans début est 0 ou positive, alors la position est définie à partir du début de la chaîne ; si elle est négative, la position est définie à partir de la fin de la chaîne. Par exemple, la ligne de code qui suit conduit au remplacement par un "X" du dernier caractère de la chaîne contenue dans $test :

    $test = 1000 ;

    $test = substr_replace ($test, "X", -1) ;

    echo $test ;

On aura donc comme résultat : 100X

L'argument longueur est optionnel, et spécifie la position dans la chaîne où l'interpréteur PHP doit stopper le remplacement. Lorsque cet argument n'est pas fourni, la chaîne est remplacée à partir de la position début jusqu'à la fin de la chaîne.

Lorsque l'argument longueur a la valeur zéro, la chaîne remplacement est insérée dans la chaîne chaîne, sans écraser la chaîne existante.

Lorsque l'argument longueur a une valeur positive, il spécifie le nombre de caractères qui doivent être remplacés par l'argument nouvelle_chaîne.

Lorsque l'argument longueur contient une valeur négative, il spécifie la position à partir de laquelle doit s'interrompre le remplacement, comptée à partir de la fin de la chaîne chaîne.

Jeux et classes de caractères :

La possibilité d'utiliser des jeux de caractères dans les expressions régulières rend celles-ci beaucoup plus puissantes pour les opérations de recherche que les simples expressions exactes. Les jeux de caractères peuvent être utilisés pour rechercher un caractère d'un type particulier, un peu à la manière d'un joker.

Tout d'abord, le caractère point (.) peut être utilisé comme jocker, pour représenter tout autre caractère, excepté le caractère de nouvelle ligne (\n.) Ainsi, l'expression régulière est : .at

Peut-elle être mise en correspondance, entre autres, avec les chaînes "cat", "sat", ou "mat". Ce type de joker s'emploie souvent pour rechercher des noms de fichiers dans les systèmes d'exploitation.

Avec une expression régulière, vous pouvez préciser le type du caractère à rechercher. Vous pouvez même définir un jeu de caractères auquel le caractère recherché devra appartenir. Dans l'exemple précédent, l'expression régulière correspondait à "cat" et "mat". Cette expression régulière correspond également à "#at". Pour spécifier que le caractère à mettre en correspondance doit être une lettre située entre a et z, vous pouvez utiliser la formulation suivante :

    [a-z]

La paire de crochets, [et], définit une classe de caractères, c'est-à-dire un jeu de caractères auquel doit appartenir le caractère recherché. Notez que l'expression spécifiée entre les deux crochets ne correspond qu'à un caractère seulement.

Vous pouvez définir un jeu de caractères sous la forme d'une liste, comme suit :

    [aeiouy]

Cette expression indique que le caractère recherché doit être une voyelle.

Vous pouvez également spécifier une plage de caractères, en utilisant des tirets, comme dans l'expression [a-z], ou un ensemble de plages de caractères, de la manière suivante :

    [a-zA-Z]

Cette expression spécifie que le caractère recherché doit être une lettre, indifféremment majuscule ou minuscule.

Un jeu de caractères peut aussi s'employer, en spécifant que le caractère recherché ne doit pas appartenir au jeu. Par exemple :

    [^a-z]

Décrit tout caractère qui n'est pas situé entre a et z. L'accent circonflexe placé entre crochet est synonyme de négation. Spécifié hors des crochets, il prend une autre signification sur laquelle nous reviendrons un peu plus loin de cette leçon.

Vous pouvez définir votre propres jeux et classes de caractères, mais vous pouvez également utiliser dans les expressions régulières des classes de caractères prédéfinies dans PHP. Celles-ci sont décrites dans la figure 6 du tableau ci-après :

Fig. 6. - Classes de caractères utilisables dans les expressions régulières de style POSIX :
Classe | Correspondance
[[:alnum:]] | Caractères alphanumériques
[[:alpha:]] | Caractères alphabétiques
[[:lower:]] | Lettres en majuscules
[[:upper:]] | Lettres en minuscules
[[:digit:]] | Décimales
[[:xdigit:]] | Chiffres hexadécimaux
[[:punct:]] | Ponctuation
[[:blank:]] | Tabulations et espaces
[[:space:]] | Caractères d'espace blanc
[[:cntrl:]] | Caractères de contrôle
[[:print:]] | Tous les caractères imprimables
[[:graph:]] | Tous les caractères imprimables, excepté le caractère espace

Répétition :

Lors d'une recherche, il arrive fréquement qu'il soit nécessaire de spécifier que le motif recherché peut être une chaîne particulière ou une classe de caractères répétée plusieurs fois. Pour représenter une telle répétition, il suffit d'utiliser deux caractères spéciaux dans l'expression régulière. Le symbole * indique que le motif peut être répété zéro ou plusieurs fois, tandis que le symbole + indique que le motif peut être répété une ou plusieurs fois. Le symbole doit être spécifié directement après la part de l'expression à laquelle il s'applique. Par exemple :

    [[:alnum:]]+

Signifie "au moins un caractère alphanumérique".

Sous-expressions :

Il apparaît souvent très utile de pouvoir scinder une expression en sous-expressions, de sorte, par exemple, à signifier "au moins une de ces chaînes suivie par exactement l'une d'entre elles". L'usage de parenthèses permet de formuler ce type de spécification, exactement comme c'est le cas dans les expressions arithmétiques. Par exemple :

    (très)* large

Correspond à "large", "très large", "très très large", et ainsi de suite.

Dénombrement de sous-expressions :

Vous pouvez spécifier le nombre de fois qu'une sous-expression peut être répétée, au moyen d'une expression numérique placée entre accolades ({}). Vous avez ainsi la possibilité d'indiquer un nombre fixe de répétition ({3}), une plage de répétition ( {2, 4} signifie de 2 à 4 répétitions), ou bien encore une plage de répétition ouverte ({2,} signifie au moins deux répétitions).

Par exemple :

    (très) {1, 3}

Correspond à "très", "très très" et "très très très".

Ancrage au début ou à la fin d'une chaîne :

Vous pouvez spécifier qu'une sous-expression particulière doit apparaître en début, et/ou à la fin de la chaîne explorée. Cette possibilité se révèle précieuse pour s'assurer que seule l'expression recherhée, et aucune autre, n'apparaît dans la chaîne trouvée.

Le symbole accent circonflexe (^) s'utilise en début d'expression régulière pour indiquer que le motif recherché doit figurer au début de la chaîne explorée. A l'inverse, le symbole $ s'utilise en fin d'expression régulière pour indiquer que le motif recherché doit figurer à la fin de la chaîne explorée.

Par exemple, l'expression régulière esr la suivante :

    ^Jean

Décrit l'occurrence de "Jean" au début d'une chaîne, tandis que :

    com$

Décrit l'occurrence de com à la fin d'une chaîne.

Enfin, l'expression :

    ^[a-z]$

Spécifie "tout caractère compris entre a et z, et formant une chaîne en soi".

Branchement :

Un trait vertical s'utilise pour représenter un choix dans une expression régulière. Par exemple, pour rechercher com, ou edu, ou net, nous pouvons utiliser l'expression suivante :

    (com) | (edu) | (net)

Recherche littérale de caractères spéciaux :

Pour rechercher un des caractères spéciaux mentionnés dans cette section, tel que ., {, ou $, vous devez le faire précéder d'une barre oblique inversée (\). Par exemple, pour représenter une barre oblique inversée, vous devez spécifier deux barres obliques inversées, \\.

Récapitulatif sur les caractères spéciaux :

Les figures 7 et 8 des tableaux donnent un récapitulatif sur les caractères spéciaux. La figure 7 du tableau donne la signification des caractères spéciaux, utilisés hors de paires de crochets. La figure 8 du tableau montre la signification de caractères spéciaux, dans le cas où ils sont placés entre cochets.

Fig. 7. - Récapitulatif sur les caractères spéciaux utilisés dans des expressions régulières POSIX, hors crochets :
Caractère | Signification
\ | Caractère d'échappement
^ | Correspondance en début de chaîne
$ | Correspondance en fin de chaîne
. | Correspond à tout caractère, excepté le caractère de nouvelle ligne (\n)
| | Début d'un autre choix, (se lit comme OU)
( | Début d'un sous-motif
) | Fin d'un sous-motif
* | Répétition 0 ou plusieurs fois
+ | Répétition 1 ou plusieurs fois
{ | Début d'un quantificateur min/max
} | Fin d'un quantificateur min/max

Fig. 8. - Récapitulatif sur les caractères spéciaux utilisés dans des expressions régulières POSIX, entre crochets :
Caractère | Signification
\ | Caractère d'échappement
^ | NON, seulement lorsque utilisé en position initiale
- | Utilisé pour spécifier des plages de caractères

Application au cas du formulaire "intelligent" de courrier électronique :

Dans le cadre de notre formulaire de courrier électronique, nous pouvons envisager au moins deux applications différentes aux expressions régulières. Nous pourrions tout d'abord y avoir recours pour améliorer le dispositif précédemment proposé pour la détection de la présence de termes particuliers dans les messages envoyés par les clients. En utilisant une fonction de traitement de chaîne, comme nous l'avons déjà suggéré, il nous faudrait effectuer trois recherches différentes pour localiser l'occurrence des expressions "Boutique", "Service clients", et "Vente au détail". Nous pourrions toutefois aboutir au même résultat en une seule recherche, en utilisant l'expression régulière suivante :

    Boutique | Service clients | Vente au détail

La deuxième application envisageable est la validation des adresses de courrier électronique des clients, par encodage du format standardisé d'une adresse de courrier électronique dans une expression régulière. Ce format encodé doit représenter la séquence suivante : des caractères alphanumériques et des tirets, suivis par un symbole @, puis par une chaîne de caractères alphanumériques et de tirets, suivis par un point, puis par plusieurs caractères alphanumériques et tirets et éventuellement plusieurs points, jusqu'à la fin de la chaîne. Concrètement, ce format pourrait s'encoder de la manière suivante :

    ^[a-zA-Z0-9_]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$

La sous-expression ^[a-zA-Z0-9_]+ décrit "la chaîne doit commencer par au moins une lettre, un nombre ou un caractère de soulignement, ou par une combinaison de tels caractères".

Le symbole @ représente un caractère @ littéral.

La sous-expression [a-zA-Z0-9\-]+ décrit la première partie du nom d'hôte, formée de caractères alphanumériques et de tirets. Notez que le tiret, qui est un caractère spécial, est précédé ici d'une barre oblique inversée parce qu'il est placé entre crochets.

La combinaison _. représente un point littéral (.).

La sous-expression [a-zA-Z0-9\-\.]+$ représente le reste du nom de domaine, y compris des lettres, des nombres, des tirets et plusieurs points si nécessaire, jusqu'à la fin de la chaîne.

Une analyse un tant soit peu poussée montrerait que certaines adresses de courrier électronique non valides pourraient être décrites par cette expression régulière. Il est impossible de dresser la liste de toutes ces adresses indésirables, mais, il serait utile d'en prendre quelques-unes en compte.

Maintenant que nous avons défini la notion d'expression régulière, nous allons passer, en revue les fonctions PHP qui permettent de les utiliser.

Localisation de sous-chaînes au moyen d'expressions régulières :

La localisation de sous-chaînes est la principale application des expressions régulières décrites dans les sections précédentes. preg_match() et preg_match ('i', $lien) ; (Pour la fonction eregi(), il faut simplement ajouter un i), sont les deux fonctions PHP de recherche d'expressions régulières.

Le prototype de la fonction preg_match() est le suivant :

    int preg_match (string motif, string chaîne, array [résultat]) ;

La fonction preg_match() explore la chaîne chaîne, à la recherche d'occurrence de l'expression régulière définie dans l'argument motif. Les sous-chaînes ainsi localisées dans la chaîne chaîne sont stockées dans le tableau résultat, sous la forme d'une sous-expression par élément.

La fonction preg_match ('i', $lien) ; est identique à la fonction preg_match(), si ce n'est qu'elle n'est pas sensible à la casse.

Notre formulaire de courrier électronique peut être modifié en y introduisant des expressions régulières, de la manière suivante :

    echo "&nbsp;&nbsp;&nbsp;&nbsp;<font face = 'Arial' size = '3' color = '005500'> <b>" . @$Votre_E_Mail = $_POST["Votre_E_Mail"] ;

    // Vérifie si la chaîne ressemble à un E-Mail

    if (preg_match('#^[\a-zA-Z0-9_]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$#', $Votre_E_Mail))

    {

        echo " "; // ici vous pouvez évoquer un texte de votre choix

    }

    else

    {

        echo '<SCRIPT TYPE = "TEXT/JAVASCRIPT">'

        . 'alert("Cette E-Mail est invalide : ' . $Votre_E_Mail. ' ") ; '

        . '</SCRIPT>';

        echo "<BR/>" ;

        echo "<font face = 'Arial' size = '3' color = '#0000FF'> <b>&nbsp;&nbsp;&nbsp;&nbsp; Cela ne peut pas &ecirc;tre une adresse E-Mail valide. Veuillez recommencer ! </b> </font>" ;

    }

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Remplacement de sous-chaînes au moyen d'expressions régulières :

Des expressions régulières peuvent également s'utiliser pour localiser et remplacer des sous-chaînes, tout comme nous l'avons déjà fait au moyen de la fonction str_replace(). Les deux fonctions PHP dédiées à ce type d'opération de recherche/remplacement sont preg_replace() et eregi_replace. Le prototype de la fonction preg_replace() est le suivant :

    string preg_replace (string motif, string remplacement, string chaîne) ;

Cette fonction cherche dans la chaîne chaîne les occurrences de l'expression régulière motif, et les remplace par la chaîne remplacement.

La fonction eregi_replace() est identique à la fonction preg_replace(), si ce n'est qu'elle n'est pas sensible à la casse.

Morcellement de chaînes au moyen d'expressions régulières :

La fonction split() est une autre fonction de traitement d'expression régulière très utile. Son prototype est le suivant :

    array split (string motif, string chaîne, int [max]) ;

Cette fonction scinde la chaîne chaîne en sous-chaînes, au niveau des sous-chaînes correspondant à l'expression régulière motif. Elle renvoie les sous-chaînes obtenues sous la forme d'un tableau. L'argument entier max limite le nombre d'éléments qui peuvent être stockés dans le tableau.

Par exemple, la fonction split() pourrait être mise en oeuvre pour décomposer les noms de domaine ou les dates, comme suit :

    $domaine = "Isole.Maison.Jardin.Education.Auxiliaire" ;

    $scinde = @split ("\.", $domaine) ;

    while (list($key, $value) = each ($scinde))

    echo "<BR/>" . $value ;

A noter : Cette fonction split() est obsolète mais, elle est remplacée par la fonction preg_split(), elle est pratiquement identique.

Ce code conduit à la décomposition de nom d'hôte, en ses cinq composantes, et à l'impression de chaque composante obtenue sur une ligne séparée.

Et pour finir cette leçon, de manière générale, il apparaît que les fonctions d'expression régulière sont moins efficaces que les fonctions de chaîne de même fonctionnalité. Par conséquent, lorsque les applications sont suffisamment simples pour que des fonctions de chaîne soient utilisées, mieux vaut utiliser des fonctions de chaîne que des fonctions d'expression régulière.

Pour l'instant, nous terminons cette quatrième leçon et nous verrons dans la prochaine, Les fonctions require() et include() qui sont très utilisées pour éviter de réécrire certains programmes.


Manipulation de Chaînes

Formulaire Intelligent de Saisie d'un Message (Smart Form Mail), Mise en Forme de Chaînes, Utilisation des Fonctions strtok(), substr(), Mise en Ordre des Chaînes, strcmp(), strcasecmp() et strnatcmp() (1ère partie) :

Dans cette leçon, vous verrez comment utiliser les fonctions PHP de traitement de chaînes pour mettre en forme et manipuler du texte. Nous examinerons également comment mettre en oeuvre les fonctions de traitement de chaînes et d'expressions régulières pour rechercher des mots, des phrases, ou tout autre motif au sein d'une chaîne.

Les fonctions décrites dans cette leçon, sont utiles dans divers contextes. Par exemple, vous vous trouverez sans aucun doute, souvent en situation de devoir nettoyer ou mettre en forme les données saisies par les utilisateurs, avant de les stocker dans une base de données. Les fonctions de recherche sont précieuses lors de l'élaboration d'applications de type moteur de recherche (entre autres).

Application modèle ; formulaire intelligent de saisie d'un message (Smart Form Mail) :

Nous illustrerons notre étude des fonctions de manipulation de chaînes et d'expressions régulières par le développement d'un formulaire intelligent de saisie d'un message. Nous utiliserons les scripts écrits au cours de cette leçon, pour compléter l'application du site de chez Jean-Pierre des Composants électroniques élaborée précédemment dans les leçons précédentes.

Notre objectif est ici de développer un formulaire simple, que les clients de chez Jean-Pierre pourront utiliser pour faire part de leurs réclamations et de leurs encouragements. Ce formulaire (voir figure 1) est plus élaboré que la plupart des formulaires de ce type publiés sur le Net. En effet, au lieu de transmettre le formulaire vers une adresse de courrier électronique générique, telle que feedback@domain.com, nous implémenterons un processus plus intelligent, en recherchant des mots et des phrases clés dans les données saisies par les clients, puis en transmettant le message du client à l'employé approprié de l'entreprise de chez Jean-Pierre. Par exemple, si le message transmis par le client contient le mot "publicité", il sera dirigé vers la boîte aux lettres du département de marketing. Si le message émane d'un client important, il pourra être directement transmis chez Jean-Pierre.

Nous commencerons ce projet par le script simple du Listing ci-dessous. Nous compléterons ensuite ce script au fur et à mesure de notre avancée dans cette leçon.

<HTML>

<HEAD>

<TITLE> La transmission du contenu d'un formulaire </TITLE>

</HEAD>

<BODY BGCOLOR="#CCCCCC">

<BR> <BR>

<H2> <CENTER> La transmission du contenu d'un formulaire et les commentaires des clients. </CENTER> </H2>

<H1> <CENTER> S'il vous pla&icirc;t, dites-nous ce que vous pensez ? </CENTER> </H1>

<CENTER> <FORM ACTION = "" METHOD = "POST">

<TABLE BORDER="0"> <BR> <BR>

<tr>

<TH> <font face="Arial" size="3" color="#000000"> <B> Votre Nom : </B> </font> </TD> <BR/>

<input type="text" name="Votre_Nom" size="30" maxlength="50">

</tr>

<tr>

<TH> <font face="Arial" size="3" color="#000000"> <B> <BR> <BR> Votre Adresse E-Mail : </B> </font> </TD> <BR>

<input type="text" name="Votre_E_Mail" size="30" maxlength="50"> </TD>

</tr>

<tr>

<TH> <font face="Arial" size="3" color="#000000"> <B> <BR> <BR> Vos r&eacute;actions ou vos commentaires : </B> </font> </TD> <BR>

<textarea rows="7" cols="50" name="Commentaire_du_Client" maxlength="600"> </textarea> </tr>

<tr>

<TD colspan="2" align="center"> <BR> <BR> <BR> <input type="submit" value="Envoyer vos commentaires"> </TD>

</tr>

</TABLE> </FORM> </CENTER>

<?php

$Votre_Adresse_Mail = "WebServeur-daniel.robert92@orange.fr" ;

$Votre_Sujet = "Commentaires sur le site Web" ;

$Votre_Contenu_Mail = "Le nom du client : " . $Votre_Nom . "\n"

. "E-Mail du client : " . $Votre_E_Mail . "\n"

. "Commentaire du client : \n " . $Commentaire_du_Client . "\n" ;

$From_Adresse = "De la part de WebServeur-Jean-P-92@domain.fr :" ;

mail ($Votre_Adresse_Mail, $Votre_Sujet, $Votre_Contenu_Mail, $From_Adresse) ;

?>

</BODY>

</HTML>

Notez que, en situation réelle, si l'utilisateur a bien rempli tous les champs obligatoires, par exemple, en utilisant la fonction isEmpty(). Ce test n'est pas implémenté dans le Listing ci-dessus, ni dans les autres applications modèles de nos leçons, par souci de simplification.

Le Listing ci-dessus, conduit à la concaténation des champs du formulaire, et à la transmission par courrier électronique de la chaîne résultante, à l'adresse WebServeur-daniel.robert92@orange.fr. Pour cela, la fonction mail(), que nous n'avons pas utilisée jusqu'ici, est mise en oeuvre.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1]. Ce formulaire n'étant pas terminé, il le sera dans la prochaine leçon ...

Comme son nom le suggère, la fonction mail() transmet des courriers électroniques (des mails). Elle s'emploie avec le prototype suivant :

    bool mail (string A, string Objet, string Message, string [entêtes_additionnels]) ;

Les trois premiers arguments de la fonction mail() sont obligatoires, et spécifient respectivement l'adresse à laquelle doivent être envoyés le message, l'objet du message, et le contenu du message. Le quatrième argument permet d'envoyer tout en-tête supplémentaire valide de courrier électronique. Vous trouverez une description des en-têtes E-Mails valides dans le document RFC822, qui peut être en ligne (nombre de normes Internet sont définies dans des RFC, que nous aborderons dans les prochaines leçons. Au Listing ci-dessus, le quatrième argument de la fonction mail() est utilisé pour ajouter une adresse "From:" dans le courrier. Nous aurions également pu l'employer pour insérer des champs "Reply-To" et "Cc:", entre autres. Pour ajouter plusieurs en-têtes additionnels, il suffit de les spécifier à la suite sous forme d'une chaîne, en les séparant par des caractères de nouvelle ligne (\n), comme suit :

    $entetes_supplementaires ="From: WebServeur-daniel.robert92@orange.fr\n" . "Reply-To: De la part de WebServeur-Jean-P-92@domain.fr" ;

Pour pouvoir mettre en oeuvre la fonction mail(), vous devez configurer votre installation PHP de sorte à lui notifier l'existence de votre application de messagerie électronique. Si l'exécution de votre script pose problème, relisez attentivement vos documentations ou encore allez sur leur site et vérifiez votre installation PHP.

Tout au long de cette leçon, nous améliorerons le script de base donné dans le Listing ci-dessus, en nous servant de fonctions PHP de manipulation de chaînes et d'expressions régulières.

Mise en forme de chaînes :

Les chaînes saisies par les visiteurs des sites Web (typiquement à partir d'un formulaire HTML) requièrent souvent un nettoyage pour être exploitables.

Elagage ou nettoyage des chaînes ; chop(), ltrim() et trim() :

La première étape dans le nettoyage d'une chaîne consiste souvent à en éliminer l'espace blanc superflu. Cet élégage n'est pas indispensable, mais se révèle souvent très utile lorsque les chaînes doivent être stockées dans un fichier ou dans une base de données, ou lorsqu'elles doivent être comparéees avec d'autres chaînes.

Le langage PHP offre trois fonctions permettant d'effectuer ce type de nettoyage. Dans le cadre de notre application modèle, nous utiliserons la fonction trim() pour élaguer les données entrantes, de la manière suivante : (Les modifications apportées sont en couleur verte foncée).

$Votre_Nom = trim($Votre_Nom) ;

$Votre_E_Mail = trim($Votre_E_Mail) ;

$Commentaire_du_Client = trim($Commentaire_du_Client) ;

La fonction trim() élimine l'espace blanc existant, en début et à la fin de la chaîne qui lui est fournie comme argument, et renvoie la chaîne ainsi élaguée. Les caractères d'espace blanc supprimés par la fonction trim() sont les nouvelles lignes et les retours chariot (\n et \r), les tabulations horizontales et verticales (\t et \v), les caractères de fin de chaîne (\0), ainsi que les espaces.

Selon le but recherché, les fonctions ltrim() ou chop() peuvent se révéler plus appropriées que la fonction trim(). ltrim() et chop() sont toutes deux semblables à la fonction trim(), en ce qu'elles prennent comme argument la chaîne à traiter, renvoient la chaîne mise en forme. Par contre, alors que la fonction trim() supprime l'espace blanc encadrant la chaîne, la fonction ltrim() élimine l'espace blanc uniquement au début de la chaîne (c'est-à-dire à la gauche de la chaîne), et la fonction chop() supprime l'espace blanc uniquement à la fin de la chaîne (ou à droite).

Mise en forme des chaînes en vue de leur présentation :

PHP offre tout un jeu de fonctions dédiées à la mise en forme des chaînes.

Mise en forme HTML ; la fonction nl2br()

La fonction nl2br() remplace chaque caractère de nouvelle ligne de la chaîne, qui lui est passé comme paramètre, par la balise HTML <BR>. Cette fonction est précieuse lorsque de longues chaînes doivent être imprimées dans la fenêtre du navigateur. Par exemple, nous utiliserons la fonction nl2br() pour présenter en retour au client le message transmis par ce dernier, avec une mise en forme acceptable :

    <p> Vos commentaires (ci-dessous) a été envoyé. </p>

    <p> <?PHP echo nl2br ($Votre_Contenu_Mail) ; ?> </p>

Souvenez-vous que, dans le contexte d'un codage HTML, l'espace blanc est ignoré. Par conséquent, en l'absence d'un traitement au moyen de la fonction nl2br(), le message du client sera imprimé sous la forme d'une seule ligne (à l'exception des caractères de nouvelles lignes imposés par le navigateur lui-même). La figure 2 illustre ces deux modes d'affichage, avec et sans traitement par la fonction nl2br().

Mise en forme d'une chaîne en vue de son impression :

Jusqu'ici nous avons utilisé la construction du langage PHP echo pour imprimer des chaînes dans la fenêtre du navigateur Web.

PHP offre également la fonction print(), qui est analogue à la construction echo. Toutefois, parce que print() est une fonction, elle renvoie une valeur (respectivement 0 ou 1, selon la réussite ou l'échec de l'impression).

echo, tout comme print(), conduit à l'impression de la chaîne "telle quelle". Vous pouvez toutefois appliquer une mise en forme plus sophistiquée au moyen des fonctions printf() et sprintf(). Ces deux fonctions sont essentiellement comparables à print(), excepté que la fonction printf imprime la chaîne mise en forme dans le navigateur, tandis que sprintf() renvoie la chaîne mise en forme.

Ces fonctions existent également dans le langage C. Si vous n'avez jamais programmé en C, il vous faudra peut être un peu de temps pour vous familiariser avec ces fonctions. Le jeu en vaut toutefois la chandelle, compte tenu de la puissance et de l'utilité de ces fonctions d'impression.

Les prototypes de ces fonctions sont les suivantes :

    string sprinf (string format [, divers arguments ...])

    int prinf (string format [, divers arguments ...])

Le premier argument requis par ces fonctions est une chaîne décrivant la forme de base de la sortie, avec des codes de mise en forme au lieu de variables. Les autres arguments sont des variables que l'interpréteur PHP viendra insérer dans la chaîne, en lieu et place des codes de mise en forme.

Par exemple, avec la fonction echo, nous pouvons imprimer une chaîne en y insérant une variable, comme suit :

    $total = 180 . "&nbsp; euros" ;

    echo "Montant total de la commande est : $total." ;

Le même résultat peut être obtenu au moyen de la fonction printf(), de la manière suivante :

    $total = 180 . "&nbsp; euros" ;

    printf ("Montant total de la commande est : %s.", $total) ;

Le code %s spécifié dans la chaîne à mettre en forme constitue une "spécification de conversion". Il indique à l'interpréteur PHP qu'il doit être remplacé par une chaîne. Dans le cas présent, il doit être remplacé par $total, interprétée comme étant une chaîne.

Si la valeur stockée dans $total était 180, ces deux approches conduiraient à l'impression de $total sous la forme de 180.

La fonction printf présente l'avantage qu'elle nous permet d'utiliser une spécification de conversion plus utile. En effet, nous pouvons utiliser printf, en spécifiant que la variable $total est en réalité un nombre à virgule flottante, et qu'elle doit être imprimée avec deux décimales, par l'instruction suivante :

    $total = 180 ;

    printf ("Montant total de la commande est : %.2f", $total) ;

Le résultat est de : 180,00

Plusieurs spécifications de conversion peuvent être insérées dans une même chaîne à mettre en forme. Si la chaîne à mettre en forme contient n spécifications, alors n arguments doivent être spécifiés à la suite de la chaîne. Chaque spécification de conversion est alors remplacée par l'argument correspondant, l'interpréteur PHP utilisant les arguments dans l'ordre où ils sont spécifiés. Par exemple :

    $total = 180 ;

    $total_expedition = 15 ;

    printf ("Montant total de la commande est : %.2f (avec l'exp&eacute;dition en surplus %.2f)", $total, $total_expedition) ;

Lorsqu'il traitera cette ligne de code, l'interpréteur PHP remplacera la première spécification de conversion par la valeur $total, et la seconde spécification par la valeur de $total_expedition.

Chaque spécification de conversion doit avoir le format suivant :

    %[caractère_remplissage][-][largeur][.précision]type

Toute spécification de conversion doit commencer par le symbole %. Pour imprimer en symbole %, vous devez par conséquent utiliser % %.

Le spécificateur caractère_remplissage est optionnel. S'il est spécifié, il est employé pour compléter la variable jusqu'à la largeur spécifiée. Par exemple, un caractère de remplissage s'utilise pour ajouter des zéros à des nombres tels que les compteurs.

Le symbole - est optionnel. Il spécifie que les données doivent être alignées à gauche dans le champ, au lieu d'être alignées à droite, comme c'est le cas par défaut.

Le spécificateur largeur indique à la fonction printf() la place (en caractères) qui doit être réservée à la variable.

Le spécificateur précision devrait commencer par un point décimal. Il indique le nombre de décimales à imprimer.

Le type constitue la dernière partie d'une spécification de conversion, et indique le type des données passées en argument. Les valeurs autorisées pour ce spécificateur sont décrites et extraites de nos catalogues de la figure 3 du Tableau ci-après :

Fig. 3. - Valeurs possibles pour le "type" d'une spécification de conversion :
b | L'argument est traité comme un entier, et représenté comme un nombre binaire
c | L'argument est traité comme un entier, et représenté comme un caractère
d | L'argument est traité comme un entier, et représenté comme un nombre décimal
f | L'argument est traité comme un double, et représenté comme un nombre à virgule flottante
o | L'argument est traité comme un entier, et représenté comme un nombre octal
s | L'argument est traité comme une chaîne, et représenté comme une chaîne
x | L'argument est traité comme un entier, et représenté comme un nombre hexadécimal (en minuscule)
X | L'argument est traité comme un entier, et représenté comme un nombre hexadécimal (en majuscule)

Vous avez probablement noté que des séquences telles que \n sont utilisées lors de l'impression de chaînes dans la fenêtre du navigateur. Ces séquences constituent un moyen d'imprimer, en sortie des caractères spéciaux. La séquence \n représente par exemple le caractère de nouvelle ligne. Les deux autres séquences fréquemment utilisées sont \t et \s, qui représentent respectivement le caractère de tabulation et le caractère espace.

Modification de la casse d'une chaîne :

PHP offre la possibilité de modifier la casse d'une chaîne. Dans le cas de l'application de notre modèle étudié dans cette leçon, cette possibilité n'est guère utile. Nous examinerons néanmoins quelques exemples simples où elle est très appréciable.

Considérons pour commencer la chaîne $sujet, qui contient l'objet du message, et qui est utilisée dans le courrier électronique transmis à partir du site de chez Jean-Pierre. Diverses fonctions sont à notre disposition pour en changer la casse. Les effets de ces différentes fonctions sont résumés dans le tableau de la figure 4.

Dans le tableau de la figure 4, la première colonne indique le nom de la fonction, la deuxième colonne décrit l'effet de la fonction considérée, la troisième colonne montre comment la fonction serait appliquée à la chaîne $sujet, tandis que la dernière colonne donne la valeur qui serait renvoyée par la fonction.

Fig. 4. - Fonctions de modification de la casse d'une chaîne, avec leurs effets :
Fonction | Description | Usage | Valeur renvoyée
 |  | $sujet | Commentaires sur le site
strtoupper() | Convertit la chaîne en majuscule | strtoupper ($sujet) | COMMENTAIRES SUR LE SITE
strtolower() | Convertit la chaîne en minuscule | strtolower ($sujet) | commentaires sur le site
ucfirst() | Met en majuscule la première lettre de la chaîne, si ce caractère est alphabétique | ucfirst ($sujet) | Commentaires sur le site
ucwords() | Met en majuscule la première lettre de chaque mot de la chaîne qui commence par un caractère alphabétique | ucwords ($sujet) | Commentaires Sur Le Site

Par Exemple :

    $sujet = "commentaires sur le site !" ;

    $sujet = strtoupper ($sujet) ;

    echo "$sujet" ;

    Résultat attendu : COMMENTAIRES SUR LE SITE !

Mise en forme de chaînes en vue de leur stockage ; AddSlaches() et StripSlashes() :

Si les fonctions de traitement de chaîne permettent de modifier la présentation visuelle des chaînes, certaines d'entre elles peuvent également être employées pour mettre les chaînes en forme, en préparation d'un stockage dans une base de données. Bien que l'écriture dans une base de données ne soit pas abordée dans cette leçon avant les prochaines, nous traiterons dès maintenant la mise en forme des chaînes, en vue de leur stockage dans une base de données que l'on verra plus tard.

Certains caractères dont la présence est autorisée au sein d'une chaîne peuvent se révéler une source de problème, particulièrement lors de l'insertion des données dans une base de données. Une base de données interprète, en effet certains caractères comme des caractères de contrôle. Les caractères les plus problématiques sont les guillemets (simples et doubles), les barres obliques inversées (\), et le caractère NUL.

Il est par conséquent nécessaire de marquer, ou d'échapper, ces caractères, de telle sorte qu'une base de données telle que MySQL les traite en tant que caractères littéraux, et non pas comme des séquences de contrôle. Pour échapper ces caractères, il suffit de les faire précéder d'une barre oblique inversée. Par exemple, le caractère " (guillemet double) doit être noté sous forme \" (barre oblique inversée guillemet double), et le caractère \ (barre oblique inversée) doit être représenté par la séquence d'échappement \\ (deux barres obliques inversées successives).

Notez que ce mode de représentation est universel pour tous les caractères spéciaux. Par conséquent, pour échapper la séquence \\ dans une chaîne, vous devez utiliser la séquence d'échappement \\\\.

PHP offre deux fonctions spécialement dédiées à l'échappement des caractères. Avant d'écrire une chaîne dans une base de données, vous devez la traiter au moyen de la fonction AddSlashes(), comme dans l'exemple suivant :

    $retour_information = AddSlashes ($retour_information) ;

Comme nombre d'autres fonctions de traitement de chaînes, la fonction AddSlashes() renvoie la chaîne qui lui a été passée comme argument, mise en forme.

Après avoir été traitée au moyen de la fonction AddSlashes(), une chaîne peut être stockée dans la base de données, avec les barres obliques inversées qui y ont été introduites. Lors de la récupération de la chaîne, vous devez alors prendre soin de supprimer ces barres obliques d'échappement. Pour cela, vous pouvez mettre en oeuvre la fonction StripSlashes(), comme suit :

    $retour_information = StripSlashes ($retour_information) ;

La figure 5 illustre l'effet produit par ces fonctions lorsqu'elles sont appliquées à des chaînes.

PHP peut être configuré de sorte à ajouter et à éliminer automatiquement des barres obliques d'échappement. On parle alors d'utilisation de guillemets magiques. Cette possibilité sera décrite dans les prochaines leçons.

Fusion et scission de chaînes au moyen de fonctions de traitement de chaîne :

Il apparaît souvent nécessaire d'examiner et de traiter certaines parties d'une chaîne séparément du reste de la chaîne. Par exemple, nous pourrions vouloir examiner les mots composant une phrase pour vérifier l'orthographe de cette dernière, ou scinder un nom de domaine ou une adresse de courrier électronique, en ses différentes composantes. PHP met à votre disposition plusieurs fonctions de traitement de chaîne et une fonction de traitement d'expression régulière permettant d'opérer ce type de manipulation.

Dans le cadre de notre application modèle, supposez que Jean-Pierre veuille recevoir personnellement tous les messages client provenant de grosclient.com Nous pouvons satisfaire son souhait en décomposant l'adresse de courrier électronique fournie par le clients, et en examinant si elle contient la sous-chaîne grosclient.com.

Utilisation des fonctions explode(), implode() et join()

explode() est la première fonction que nous pouvons mettre en oeuvre pour atteindre notre objectif. Son prototype est le suivant :

    array explode (string séparateur, string entrée) ;

Cette fonction prend une chaîne comme deuxième argument (entrée) et la scinde au niveau de chaque occurrence du séparateur spécifié comme premier argument. Les différentes sous-chaînes ainsi obtenues sont renvoyées sous forme d'un tableau.

Dans le cadre de notre application modèle, nous pouvons extraire le nom de domaine de l'adresse de courrier électronique du client par le biais du code suivant :

    $Votre_E_Mail_array = explode ("@", $Votre_E_Mail) ;

L'exécution de cette ligne de code conduit à la scission de l'adresse de courrier électronique du client en deux parties : le nom d'utilisateur, qui est stocké dans $Votre_E_Mail_array[0], et le nom de domaine, qui est stocké dans $Votre_E_Mail_array[1].

Nous pouvons alors identifier l'origine du client, en testant le nom de domaine. Ne reste plus ensuite qu'à transmettre le message saisi par le client à la personne appropriée :

    if ($Votre_E_Mail_array[1] == "grosclient.fr")

    $Votre_Adresse_Mail = "WebServeur-daniel.robert92@orange.fr" ;

    else

    $Votre_Adresse_Mail = "Jean-p9.old@orange.fr" ;

Notez que si le nom de domaine est défini en lettres majuscules, le code précédent ne conduira pas au résultat recherché. Pour éviter ce problème, nous pouvons convertir l'ensemble des caractères du nom de domaine en majuscules, ou bien en minuscules, avant d'effectuer notre test :

    $Votre_E_Mail_array[1] = strtoupper ($Votre_E_Mail_array[1]) ;

L'effet produit par la fonction explode() peut être annulé, en mettant en oeuvre la fonction implode(), ou la fonction join(). Ces deux fonctions sont identiques. Par exemple, la ligne de code qui suit :

    $Votre_E_Mail_array = array ("Votre_Nom", "Votre_E_Mail", "Votre_Contenu_Mail") ;

    $Comme_Separateur = implode("&nbsp;&nbsp;@&nbsp;&nbsp;", $Votre_E_Mail_array);

Opère la recombinaison de tous les éléments du tableau $Votre_E_Mail_array, en les joignant au moyen de la chaîne passée comme premier argument. Cet appel de fonction est très semblable à celui de la fonction explode(), mais produit le résultat opposé.

Utilisation de la fonction strtok() :

Contrairement à la fonction explode(), qui décompose en une seule fois une chaîne en différentes parties, la fonction strtok() extrait une à une les différentes parties d'une chaîne (token, qui peut être traduit par "maillon"). La fonction strtok() se révèle une solution très utile pour remplacer la fonction explode(), afin de traiter un à un des mots formant une chaîne de caractères.

Le prototype de la fonction strtok() est le suivant :

    string strtok (string entrée, string séparateur) ;

L'argument séparateur peut contenir soit un caractère individuel, soit une chaîne de caractères. Notez toutefois que la chaîne spécifiée dans l'argument entrée sera scindée au niveau de chacun des caractères spécifiés dans le séparateur, et non pas au niveau des occurrences de la chaîne séparateur complète (ce qui est le cas avec la fonction explode().

Le prototype donné précédemment ne fait pas apparaître toute la subtilité de la mise en oeuvre de la fonction strtok().

Pour obtenir le premier "maillon" d'une chaîne, invoquez la fonction strtok(), en lui passant la chaîne à décomposer, ainsi que le séparateur à utiliser. Pour obtenir les maillons suivants, il suffit de passer un seul paramètre : le séparateur, la fonction strtok() conserve, en effet un pointeur interne sur la chaîne qui lui a été passé comme argument. Pour réinitialiser le pointeur de strtok(), invoquez strtok() en spécifiant à nouveau l'argument entrée.

Voici un exemple typique d'utilisation de la fonction strtok() :

    $Retour_Information = "Les commentaires de notre client" ;

    $Maillon = strtok ($Retour_Information, " ") ;

    echo $Maillon . "<BR>" ;

    while($Maillon !== false)

    {

    $Maillon = strtok(" ") ;

    echo $Maillon . "<BR>" ;

    } ;

Le résultat est le suivant :

    Les

    commentaires

    de

    notre

    client

Comme nous l'avons déjà mentionné, il serait fortement indiqué dans l'exemple considéré ici de vérifier que le client a bien rempli les champs du formulaire de message, par exemple, au moyen de la fonction empty(). Ce test n'est pas implémenté dans les exemples de code donnés dans cette leçon, par souci de brièveté.

Le code précédent imprime sur une ligne séparée chaque maillon du message saisi par le client. Ce traitement de scission se poursuit jusqu'à la fin du message. Notez que le fonctionnement de la fonction strtok() est légèrement différent en programmation PHP et en programmation C. Lorsque la chaîne à décomposer contient plusieurs instances successives d'un séparateur (deux espaces dans notre exemple), la fonction strtok() renvoie une chaîne vide. Etant donné qu'une chaîne vide est également renvoyée lorsque la fin de la chaîne est atteinte, il y a risque de confusion. De plus, si un des maillons est de valeur 0, la fonction strtok() renvoie également une chaîne vide. Cette limitation rend la fonction PHP strtok() un peu moins utile que la fonction strtok() du langage C. De ce fait, l'utilisation de la fonction explode() est souvent préférable.

Utilisation de la fonction substr() :

La fonction substr() permet d'accéder à une sous-chaîne d'une chaîne, en spécifiant les points de début et de fin de la sous-chaîne. Dans le cadre de l'exemple considéré ici, cette fonction n'a guère d'utilité, mais elle se révèle précieuse lorsqu'il est nécessaire de traiter des portions particulières de chaînes.

La fonction substr s'utilise avec le prototype suivant :

    string substr (string chaîne, int début, int [longueur]) ;

La fonction substr() renvoie une sous-chaîne extraite de la chaîne passée comme argument chaîne.

Pour illustrer l'usage de cette fonction, considérons l'exemple de chaîne suivant :

    $test = "Votre service à la clientèle est excellent" ;

    echo substr($test, 1) ;

Si la fonction substr() est invoquée, en spécifiant uniquement un nombre positif comme argument début, vous obtiendrez la sous-chaîne comprise entre la position début, et la fin de la chaîne. Par exemple, l'exécution de l'instruction suivante :

    echo substr($test, 15) ;

Renvoie "la clientèle est excellent". Notez que les positions dans la chaîne sont numérotées à partir de 0, comme dans les tableaux.

Lorsque la fonction substr() est appelée, en spécifiant uniquement un nombre négatif comme argument début, vous obtenez la sous-chaîne se terminant à la fin de la chaîne et commençant à la position définie par la position de la fin de la chaîne moins longueur caractères. Par exemple, l'exécution de l'instruction qui suit :

    $test = "Votre service à la clientèle est excellent" ;

    echo substr($test, -9) ;

Renvoie la sous-chaîne "excellent".

L'argument longueur permet de spécifier soit le nombre des caractères à renvoyer (si la longueur est un nombre positif), soit le caractère final de la sous-chaîne renvoyée (si la longueur est un nombre négatif). Par exemple, l'exécution de l'instruction qui suit :

    $test = "Votre service à la clientèle est excellent" ;

    echo substr($test, 0, 13) ;

Renvoie les treize caractères de la chaîne, c'est-à-dire "Votre service". La ligne de code suivant :

    $test = "Votre service à la clientèle est excellent" ;

    echo substr($test, 5, -13) ;

Renvoie la sous-chaîne comprise entre le cinquième caractère et le treizième caractère compté à partir de la fin de la chaîne, c'est-à-dire "service à la clientèle".

Comparaison de chaînes :

Jusqu'à présent, nos seules comparaisons de chaînes se sont limitées au test de l'égalité entre deux chaînes, au moyen de l'opérateur ==. Le langage PHP permet d'opérer des comparaisons plus sophistiquées, que nous classerons en deux catégories : les correspondances partielles, et les autres. Nous commencerons par étudier "les autres", et nous examinerons dans un deuxième temps, les correspondances partielles, dont nous aurons besoin pour poursuivre le développement de notre application modèle.

Mise en ordre des chaînes ; strcmp(), strcasecmp() et strnatcmp() :

Ces fonctions permettent d'ordonner des chaînes les unes par rapport aux autres. Elles sont précieuses lors du tri de données.

Le prototype de la fonction strcmp() est le suivant :

    int strcmp (string chaîne_1, string chaîne_2) ;

La fonction strcmp() compare les deux chaînes qui lui sont passées comme arguments. Elle renvoie 0 si les deux chaînes apparaissent égales. Si la chaîne_1 vient après (ou est supérieure à) chaîne_2 d'après l'ordre lexicographique, alors la fonction strcmp() renvoie un nombre supérieur à zéro ; si c'est l'inverse, strcmp() renvoie un nombre inférieur à zéro. Cette fonction est sensible à la casse.

La fonction strcasecmp() est identique à strcmp(), si ce n'est qu'elle n'est pas sensible à la casse.

La fonction strnatcmp() et son homologue non sensible à la casse strnatcasecmp() sont des nouveautés de la version 5 et autres de PHP. Ces fonctions comparent les chaînes d'après l'ordre "naturel", et s'inspirent du comportement humain. Par exemple, la fonction strcmp() classerait la chaine "2" après la chaîne "12", parce que cette dernière est supérieure d'un point de vue lexicographique. Par contre, la fonction strnatcmp() effectuerait le classement inverse. Vous trouverez plus d'informations sur la notion d'ordre naturel via Internet.

Détermination de la longueur d'une chaîne au moyen de la fonction strlen() :

Nous pouvons tester la longueur d'une chaîne, en faisant appel à la fonction strlen(). Celle-ci renvoie la longueur de la chaîne qui lui est passée comme argument. Par exemple, strlen ("Nos clients") renvoie la valeur 11, en comptant l'espace blanc.

La fonction strlen() est utile pour valider les données saisies par l'utilisateur. Par exemple, considérons le cas de l'adresse de courrier électronique entrée dans le formulaire de notre application modèle, et stockée dans la variable $Votre_E_Mail. Vérifier la longueur du contenu d'une variable stockant une adresse email constitue une des méthodes de base de validation de l'adresse de courrier électronique stockée. Une adresse de courrier électronique valide doit compter au moins six caractères (a@a.fr) dans le cas minimaliste d'une adresse se composant d'un code de pays sans deuxième niveau de domaine, d'un nom de serveur à un caractère, et d'une adresse E-Mail d'une seule lettre. Un message d'erreur devrait par conséquent être généré si l'adresse saisie n'a pas la longueur minimale :

    if (strlen ($Votre_Adresse_Mail) < 6 )

    {

        echo "Cette adresse e-mail n'est pas valide" ;

        exit ; // Fin de l'ex&eacute;cution du script PHP

    }

Il s'agit là, bien sûr, d'une méthode simpliste de validation de l'information. Nous verrons de meilleures méthodes dans la prochaine section.

Pour l'instant, nous terminons cette quatrième leçon du premier chapitre et nous verrons dans la prochaine la suite du second chapitre tels que, Localisation de sous-chaînes dans des chaînes strstr(), strchr(), str_replace(), substr_replace(), jeux et classes de caractères, etc. ...


Passer par référence contre passer par valeur

Utilisation de fonctions (suite), en PHP (3ème partie) :

Passer par référence contre passer par valeur :

Pour implémenter une fonction appelée incrementation(), et permettant d'incrémenter une valeur, nous pourrions être tenté d'écrire le code suivant :

    function incrementation ($value, $montant = 1)

       {

          $value = $value + $montant ;

       }

Ce code ne produit pourtant pas le résultat recherché : l'exécution des lignes suivantes produit la valeur "10" comme résultat :

    $value = 10 ;

    incrementation ($value) ;

    echo $value ;

L'appel de la fonction incrementation() ne provoque aucune modification du contenu de la variable $value. Ce résultat est directement l'expression des règles de portée. Le code de cet exemple crée une variable appelée $value, qui contient la valeur 10. Il invoque ensuite la fonction incrementation(). La variable $value utilisée au sein de la fonction incrementation() est créée au moment de l'appel de la fonction. L'interpréteur PHP ajoute 1 à cette variable, qui prend par conséquent la valeur 11 au sein de la fonction, et jusqu'à la fin de la fonction. L'interpréteur revient ensuite au code qui a invoqué incrementation(). Dans ce code, $value est une variable différente, de portée globale, dont le contenu n'a pas changé.

Nous pourrions résoudre ce problème en déclarant $value dans la fonction, en tant que variable globale. Mais pour utiliser la fonction incrementation(), nous serions alors dans l'obligation de donner le nom $value à la variable à incrémenter. Une meilleure solution s'offre heureusement à nous : passer par "référence".

Les paramètres d'une fonction sont normalement passés à la fonction "par valeur". Lorsqu'un paramètre est passé à une fonction, l'interpréteur PHP crée une nouvelle variable contenant la valeur transmise. Il s'agit là d'une copie de la variable originale. Cette valeur copiée peut ainsi être modifiée à loisir, sans que la valeur de la variable d'origine en soit affectée (hors de la fonction).

Passer les paramètres par référence apparaît toutefois préférable, bien que ce ne soit pas l'approche la plus courante. Dans ce cas, l'interpréteur PHP, au lieu de créer une nouvelle variable pour le paramètre passé à la fonction, donne à la fonction une référence sur la variable d'origine. A cette référence est associé un nom de variable, qui commence par un signe dollar. Une référence peut être utilisée comme toute variable autre. Cependant, au lieu de posséder sa propre valeur, une référence pointe sur la valeur d'origine. Toute modification apportée à la référence est répercutée sur la variable originale.

Pour notifier qu'un paramètre est passé par référence, il suffit de le faire précéder d'une esperluette (&) dans la définition de la fonction. L'appel de la fonction ne nécessite aucune modification.

Dans l'exemple précédent, nous pouvons modifier la fonction incrementation() pour aboutir au résultat recherché, en passant à la fonction un paramètre par référence comme suit :

    function incrementation (&$value, $montant = 1)

       {

          $value = $value + $montant ;

       }

Ainsi formulée, notre fonction est opérationnelle, et nous avons toute liberté pour le choix du nom de la variable à incrémenter. Comme nous l'avons déjà mentionné, l'utilisation d'un même nom de variable au sein et hors d'une fonction est source de confusion pour les humains, si bien que nous attribuerons un nouveau nom à la variable utilisée dans le script principal. Le code de test qui suit conduit à l'affichage du nombre 10 dans la fenêtre du navigateur avant l'appel de la fonction incrementation(), et du nombre 11 après l'appel de la fonction.

    $nombre = 10 ;

    echo $nombre ;

    incrementation ($nombre) ; // Appel de la fonction incrementation par Référence

    echo $nombre ;

Sortie forcée d'une fonction :

Le mot clé return permet d'interrompre l'exécution d'une fonction. Lorsque l'exécution d'une fonction prend fin, soit parce que toutes ses instructions ont été exécutée, soit parce que le mot clé return a été atteint, l'exécution se poursuit par un retour à l'instruction qui fait suite à l'appel de la fonction.

A l'appel de la fonction suivante, seule la première instruction echo est exécutée :

<?PHP

    function retour_d_essai()

       {

          echo " Cette d&eacute;claration sera ex&eacute;cut&eacute;e " ;

          return ;

          echo " Cette d&eacute;claration ne sera jamais ex&eacute;cut&eacute;e " ;

       }

          retour_d_essai() ; // Appel de la fonction

?>

Cet usage du mot clé return n'est évidemment pas des plus utiles. Normalement, le mot clé return s'emploie pour sortir d'une fonction, au milieu de la fonction, lorsqu'une condition spécifiée a été satisfaite.

Une condition d'erreur représente ainsi une raison typique de mise en œuvre d'une instruction return, pour interrompre l'exécution d'une fonction avant sa fin. Par exemple, supposez qu'il nous faille écrire une fonction déterminant, quel est le plus grand de deux nombres ? Il faudrait que l'exécution de la fonction puisse être interrompue si l'un des deux nombres n'a pas été fourni.

<?PHP

    function plus_grand ($x, $y)

       {

          if (!isset ($x) || !isset ($y))

          {

       echo " <BR /> Cette fonction n&eacute;cessite uniquement que deux nombres. " ;

       return ;

          }

          if ($x >= $y)

          echo "<BR />" . $x ;

          else

          echo $y ;

       }

La fonction prédéfinie isset() permet de déterminer si une variable a bien été créée, et si elle contient une valeur. Dans le code précédent, un message d'erreur est généré et l'exécution de la fonction s'interrompt si l'un des paramètres n'a pas été fourni avec une valeur. Pour cela, un test par !isset() est effectué. !isset() signifie "NON isset()", et l'instruction if de ce fragment de code peut être lu comme "si x n'est pas ajustée ou si y n'est pas ajustée". L'exécution s'interrompt si l'une de ces conditions est vraie.

Lorsque l'interpréteur PHP atteint une instruction return dans une fonction, il n'exécute pas les lignes de la fonction qui suivent l'instruction return. L'exécution se poursuit au niveau du point du programme où se situe l'appel de la fonction. Si les deux paramètres sont bien ajustés, la fonction affiche dans la fenêtre du navigateur la valeur du plus grand des deux paramètres ou nombres.

Et enfin, pour l'exécution du code suivant concernant le programme ci-dessus :

    $a = 1 ;

    $b = 4.5 ;

    $c = 2.9 ;

    plus_grand ($a, $b) ;

    plus_grand ($c, $a) ;

    plus_grand (@$d, $a) ;

?>

Conduit au résultat suivant :

    4.5

    2.9

    Cette fonction n&eacute;cessite uniquement que deux nombres.

Renvoi de valeurs par des fonctions :

L'usage du mot clé return ne se limite pas à l'interruption de l'exécution d'une fonction. Dans nombre de fonctions, une instruction return est mise en œuvre pour communiquer avec le code qui a invoqué la fonction. La fonction plus_grand() pourrait se révéler plus utile si le résultat de la comparaison effectuée était renvoyé au lieu d'être affiché dans le navigateur. C'est alors dans le code du script principal que se déciderait l'affichage ou l'utilisation de ce résultat. La fonction max() prédéfinie dans PHP a exactement cette fonctionnalité.

<?PHP

    function plus_grand ($x, $y)

       {

          if (!isset ($x) || !isset ($y))

          return - 1.7E+308 ;

          else if ($x >= $y)

          return $x ;

          else

          return $y ;

       }

          $a = 1 ;

          $b = 4.5 ;

          $c = 2.9 ;

La fonction plus_grand() renvoie à présent la plus grande des deux valeurs qui lui sont passées comme paramètres. Une valeur bien sûr différente est renvoyée en cas d'erreur. Si l'un des nombres à comparer n'est pas fourni, la fonction renvoie le nombre - 1.7 x 10308, qui est très petit et peu susceptible d'être confondu avec une réponse valide. La fonction prédéfinie max() a un comportement légèrement différent, puisqu'elle ne renvoie rien lorsque les deux variables à la fois n'ont pas été fournies. Lorsque seulement une des deux variables a été fournie, max() renvoie la valeur de cette variable.

Pour information :

Pourquoi choisir le nombre - 1.7 x 10308 ? Dans nombre de langages, des valeurs minimales et maximales sont imposées pour les nombres. Ce n'est malheureusement pas le cas avec PHP. Le nombre - 1.7 x 10308 est le plus petit nombre supporté par la version 4.0 de PHP. Si ce type de comportement est important dans vos projets, gardez bien à l'esprit que cette limite n'est pas garantie pour les versions futures. Etant donné que la limite en taille actuelle est basée sur le type de données double du langage C sous-jacent, elle peut varier d'un système d'exploitation ou d'un compilateur à l'autre.

Le code qui suit du programme ci-dessus :

    echo plus_grand ($a, $b) . "<BR />" ;

    echo plus_grand ($c, $a) . "<BR />" ;

    echo plus_grand (@$d, $a) . "<BR />" ;

?>

Produit le résultat suivant :

    4.5

    2.9

    - 1.7E+308

Souvent, les fonctions qui accomplissent des tâches, mais qui n'ont pas à renvoyer de valeur, renvoient les valeurs true ou false pour signaler si elles ont réussi ou échoué. Les valeurs true et false peuvent être respectivement représentées par 1 et 0.

Blocs de code :

Pour déclarer qu'un groupe d'instructions constitue un bloc de code, il suffit de le placer entre accolades. Le fonctionnement du code s'en trouve très peu affecté. Par contre, la déclaration d'un bloc de code a des implications spécifiques, notamment sur la manière dont sont exécutées les structures de contrôle telles que les boucles et les structures conditionnelles.

Les deux exemples de code qui suivent donnent ainsi des résultats très différents.

Exemple sans bloc de code :

<?PHP

          echo " <BR /> " ;

       for ($i = 0 ; $i < 3 ; $i++)

          echo "&nbsp; Ligne 1 <BR />" ;

          echo "&nbsp; Ligne 2 <BR />" ;

          echo "&nbsp; Ligne 3 <BR />" ;

?>

Exemple avec bloc de code :

<?PHP

          echo " <BR /> " ;

       for ($i = 0 ; $i < 3 ; $i++)

       {

          echo "&nbsp; Ligne 1 <BR />" ;

          echo "&nbsp; Ligne 2 <BR />" ;

          echo "&nbsp; Ligne 3 <BR />" ;

       }

?>

Dans ces deux exemples, la boucle for est répétée trois fois de suite. Dans le premier exemple, seule l'instruction qui succède immédiatement à l'instruction for est exécutée dans la boucle. Le résultat obtenu est le suivant :

    Ligne 1

    Ligne 1

    Ligne 1

    Ligne 2

    Ligne 3

Dans le second exemple, un bloc de code est mise en œuvre pour regrouper trois lignes de code. Il s'ensuit que les trois lignes ainsi regroupées sont exécutées trois fois de suite dans la boucle for, avec le résultat suivant :

    Ligne 1

    Ligne 2

    Ligne 3

    Ligne 1

    Ligne 2

    Ligne 3

    Ligne 1

    Ligne 2

    Ligne 3

Grâce aux mises en retrait du code, la différence entre ces deux exemples apparaît au premier coup d'œil. La mise en retrait vise à donner aux lecteurs du code une indication visuelle sur les lignes qui sont affectées à la boucle for. Notez que l'insertion de caractères espace dans le code n'affecte pas la manière dont l'interpréteur PHP traite le code.

Dans certains langages, les blocs de code affectent la portée des variables. Ce n'est pas le cas en PHP.

Récursion :

Le langage PHP supporte les fonctions récursives. Une fonction "récursive" est une fonction qui s'appelle elle-même. Ce type de fonction se révèle particulièrement utile pour naviguer dans des structures de données dynamiques, telles que des listes et des arborescences liées.

Toutefois, les applications orientées Web qui requièrent des structures de données d'une telle complexité sont assez rares, si bien que la possibilité de récursion n'est que rarement exploitée en PHP. Dans nombre cas, la récursion peut être utilisée à la place d'une répétition (d'une itération), parce qu'elle consiste également à opérer de manière répétitive. Les fonctions récursives sont plus lentes et consomment plus de mémoire que les itérations. Par conséquent, vous avez tout intérêt à préférer les itérations aux récursions, lorsque cela est possible.

Pour que cette étude soit complète, nous allons examiner l'exemple présenté ci-dessous.

Une chaîne peut être facilement inversée au moyen d'une récursion. La version par itération est également donnée.

<?PHP

          echo " <BR /> " ;

       function sens_inverse_recursion($str)

       {

          if (strlen($str) > 0)

          sens_inverse_recursion(substr($str, 1)) ;

          echo substr($str, 0, 1) ;

          return ;

       }

       function sens_inverse_iteration($str)

       {

          for ($i = 1; $i <= strlen($str) ; $i++)

       {

          echo substr($str, -$i, 1) ;

          }

          return ;

       }

          sens_inverse_recursion ("Hello") ;

          echo "<BR />" ;

          sens_inverse_iteration("Hello") ;

?>

Le programme ci-dessus contient deux fonctions, qui impriment toutes deux à l'envers la chaîne qui leur est fournie comme argument. La fonction sens_inverse_recursion() est récursive, tandis que la fonction sens_inverse_iteration() est itérative.

La fonction sens_inverse_recursion() prend une chaîne comme paramètre. Lorsqu'elle est invoquée, elle opère en s'appelant elle-même, et en se passant chaque fois du deuxième au dernier caractère de la chaîne. Par exemple, cet appel :

    sens_inverse_recursion("Hello") ;

Se traduit par la série d'appels suivante :

    sens_inverse_recursion("ello") ;

    sens_inverse_recursion("llo") ;

    sens_inverse_recursion("lo") ;

    sens_inverse_recursion("o") ;

    sens_inverse_recursion("") ;

Chaque fois que la fonction s'appelle elle-même, une nouvelle copie du code de la fonction est effectuée dans la mémoire du serveur, mais avec un paramètre différent. Tout se passe comme si une fonction différente était invoquée chaque fois. Ce fonctionnement permet d'éviter la confusion entre les différentes instances de la fonction.

A chaque appel, la longueur de la chaîne est évaluée. Lorsque l'interpréteur PHP atteint la fin de la chaîne (strlen() == 0), la condition n'est plus satisfaite. L'instance de la fonction la plus récente (sens_inverse_recursion("")) se poursuit par l'exécution de la prochaine ligne de code, qui conduit à l'impression du premier caractère de la chaîne qui a été passée comme paramètre. A ce stade, il n'y a pas de caractère, parce que la chaîne est vide.

Ensuite, cette instance de la fonction renvoie le contrôle à l'instance qui l'a appelée, c'est-à-dire sens_inverse_recursion("o"). Celle-ci imprime le premier caractère de sa chaîne, en l'occurence "o", et renvoie le contrôle à l'instance qui l'a invoquée.

Le processus se poursuit ainsi, imprimant un caractère puis renvoyant le contrôle à l'instance précédente de la fonction dans l'ordre d'appel, jusqu'à ce que le contrôle soit renvoyé au programme principal

Nous terminons cette cinquième leçon et nous verrons dans la prochaine, l'usage de certaines Créations de Classes puis nous aborderons la Base de Données ainsi que le codage MySQL.


Implémentation d'une Classe

Programmation orientée objets (2ème partie) :

Implémentation d'une classe :

Une fois que le résultat visé et la fonctionnalité recherchée ont été soigneusement définis, nous pouvons attaquer à l'implémentation.

La conception et la gestion de projets d'envergure sont traitées un peu plus loin dans ce deuxième chapitre. Pour l'heure, nous nous limiterons aux aspects spécifiques de l'implémentation PHP orientée objets.

Nous devons attribuer à notre classe un nom logique et explicite. Etant donné que la classe représentera une page Web, nous l'appellerons simplement Page. Pour déclarer une classe dénommée Page.inc, nous pouvons taper le code suisant :

  <?PHP

       class Page

       {

       }

  ?>

Notre classe doit contenir des attributs. Nous définirons comme attributs de la classe Page, les éléments appelés à changer d'une page à l'autre. Nous dénommerons $content le contenu principal de la page, qui sera une combinaison de balises HTML et de texte. La variable $content peut être déclarée au sein de la définition de la classe par la ligne de code suivante :

    var $content ;

Nous pouvons également définir des attributs pour stocker le titre de la page. Pour que les visiteurs du site identifient clairement la page consultée, ce titre changera d'une page à l'autre. Pour éviter que des titres en blanc soient affichés, nous définirons un titre par défaut, via la déclaration suivante :

    var $title = "C.E.I. - Consultant &Eacute;lectronique-Informatique" ;

La plupart des pages Web des sites commerciaux comprennent des méta-balises destinées à aider les moteurs de recherche dans leur indexation. Pour que ces méta-balises soient utiles, elles doivent changer d'une page à l'autre. Là encore, nous fournirons une valeur par défaut, via la déclaration suivante :

    var $keywords = "C.E.I. - Abr&eacute;viation de trois lettres, Consultant         &Eacute;lectronique-Informatique, certains de mes meilleurs amis
        sont des moteurs de recherche" ;

Les boutons de navigation montrés sur la page de notre modèle de la figure 2, à cette adresse (voir la leçon précédente) resteront probablement identiques d'une page à l'autre, afin de ne pas semer la confusion dans l'esprit du visiteur. Toutefois, pour faciliter la modification de ces boutons, nous les implémenterons également sous la forme d'attributs. Etant donné que le nombre de boutons peut être appelé à changer, nous utiliserons un tableau, dans lequel nous stockerons à la fois l'intitulé du bouton, et l'URL pointée.

    var $buttons = array( "Accueil"      => "Home.php",

                          "Contact"      => "Contact.php",

                          "Services"     => "Services.php",

                          "Plan_du_Site" => "Plan_du_Site.php"

                        );

Pour que la classe Page soit dotée d'une fonctionnalité, nous devons la munir d'opérations. Pour commencer, nous pouvons lui fournir des fonctions accesseur, qui nous permettront d'ajuster et d'accéder aux valeurs des attributs définis. Toutes ces fonctions seront implémentées sur le modèle suivant :

    function Set_Content($new_content)

    {

        $this->content = $new_content ;

    }

Parce qu'il est peu probable que nous ayons besoin de récupérer une des ces valeurs depuis l'extérieur de la classe, nous choisirons délibérément de ne pas fournir l'ensemble de fonctions GET correspondant.

Etant donné que la classe Page vise principalement à afficher une page de HTML, nous devons implémenter une fonction à cette fin. Nous dénommerons cette fonction Display() qui signifie "visualiser ou afficher", et nous la déclarerons de la manière suivante :

    function Display()

    {

      echo "<HTML> \n <HEAD> \n" ;

      $this -> Display_Title() ;

      $this -> Display_Keywords() ;

      $this -> Display_Styles() ;

      echo "</HEAD> \n <BODY> \n" ;

      $this -> Display_Header() ;

      $this -> Display_Menu($this->buttons) ;

      echo $this -> content ;

      $this -> Display_Footer() ;

      echo "</BODY> \n </HTML> \n" ;

     }

Outre, quelques simples instructions echo qui affichent le texte HTML, cette fonction comprend essentiellement des appels d'autres fonctions de la classe. Comme le laissent deviner leurs noms, ces autres fonctions affichent des parties distinctes de la page.

Un tel découpage en fonctions n'est pas indispensable. Nous aurions très bien pu combiner ces différentes fonctions en une seule. Nous avons toutefois choisi ce découpage pour diverses raisons.

Chaque fonction doit en principe accomplir une tâche définie. Plus la tâche est simple, plus la fonction est facile à tester. Ne poussez toutefois pas cette modularisation trop loin : un programme scindé en trop d'unités se révèle difficile à lire.

Grâce au concept d'héritage, nous avons la possibilité de redéfinir des opérations. Nous pouvons redéfinir une fonction Display() volumineuse, mais, il est peu probable que nous soyons amené à changer la manière dont toute la page est affichée. Il est par conséquent préférable de scinder la fonctionnalité d'affichage en quelques tâches autonomes, de sorte à pouvoir redéfinir les seules parties qui doivent être modifiables.

La fonction Display() invoque Display_Title(), Display_Keywords(), Display_Styles(), Display_Header(), Display_Menu, et Display_Footer(). Nous devons définir ces opérations. Une des améliorations apportées à la version 4 de PHP¨, par rapport à PHP 3, réside dans le fait que nous pouvons écrire des opérations ou des fonctions dans cet ordre logique, en invoquant l'opération ou la fonction avant le code de la fonction elle-même. En PHP 3, et dans nombre d'autres langages de programmation, la fonction ou l'opération doivent être écrites avant d'être appelées.

La plupart des opérations nécessaires à la classe Page sont relativement simples, et procèdent à l'affichage de code HTML, voire du contenu des attributs de la classe Page.

Le Listing ci-dessous donne l'intégralité du code de la classe Page. Ce script est enregistré dans le fichier Page.inc, en vue de son inclusion dans d'autres fichiers.

Listing 1. : Page.inc - La classe Page constitue un moyen facile et flexible de création de Pages pour le site C.E.I.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

A la lecture du Listing 1, notez que les fonctions Display_Styles(), Display_Header() et Display_Footer() doivent afficher un grand bloc de code HTML statique, sans traitement PHP. Par conséquent, ces opérations sont implémentées sous la forme d'une simple balise de fermeture PHP (?>), suivie du code HTML, puis d'une balise d'ouverture PHP (<?PHP).

La classe Page comprend deux autres opérations que celles citées dans la leçon précédente. L'opération Display_Button() génère un simple bouton de menu. Si le bouton doit pointer sur la page courante, alors, il est remplacé par un bouton inactif, d'apparence légèrement différente, et ne pointant sur aucune page. Cette astuce permet de conserver une présentation cohérente des pages du site, et donne aux visiteurs une indication sur leur localisation dans le site.

L'opération IsURLCurrentPage($url) détermine si l'URL associée à un bouton pointe sur la page courante. Nombre de techniques permettent d'implémenter ce type de test. Dans le cas présent, c'est la fonction de chaîne strpos() qui est mise en œuvre pour déterminer si l'URL donnée est contenue dans l'une des variables de serveur. L'instruction (strpos($_SERVER["PHP_SELF"], $url) == false) renvoie un nombre si la chaîne stockée dans $url est contenue dans la variable globale $_SERVER, et renvoie la valeur false dans le cas contraire.

Pour utiliser la classe Page, nous devons inclure le fichier Page.inc dans un script, et invoquer Display().

Le code donné au Listing 2 crée la page d'accueil du site de l'entreprise fictive C.E.I. - (Consultant Électronique-Informatique), et donne un résultat très semblable à celui montré dans [l'exemple 3], ci-dessus.

Le code du Listing 2 opère de la manière suivante :

  • Il utilise l'instruction require pour inclure le contenu de Page.inc qui stocke la définition de la classe Page.

  • Il crée une instance de la classe Page. Cette instance est appelée $Home_Page.

  • Il invoque l'opération Set_Content() au sein de l'objet $Home_Page, en passant le texte et les balises HTML qui doivent produire le contenu spécifique à la page.

  • Il invoque l'opération Display() au sein de l'objet $Home_Page pour provoquer l'affichage de la page dans le navigateur Web du visiteur.

Listing 2. : Home_2.php - Cette page d'accueil est obtenue en utilisant la classe Page pour accomplir l'essentiel du travail nécessaire à la génération de la page

Le listing 2 montre la facilité avec lequel de nouvelles pages Web peuvent être ajoutées au site lorsque la classe Page est utilisée. En outre, cette approche permet d'obtenir des pages d'apparence très similaire sur l'ensemble du site.

Pour utiliser une variante de la page standard dans une certaine partie du site, il suffit de copier Page.inc dans un nouveau fichier appelé Page_2.inc et d'apporter les modifications voulues. Toutefois, après avoir opéré une telle "scission" de notre modèle, nous devrons reproduire dans le fichier Page_2.inc les mises à jour effectuées dans la Page.inc (le cas échéant). Nous mettons les deux autres fichiers à savoir Contact.php et Plan_du_Site.php afin de faciliter vos essais. Nous mettons également le reste des pages que vous trouverez en bas de cette leçon, dans la totalité du site, vous aurez 10 pages que vous pouvez faire (copier/coller).

Listing 3. : Contact.php - Cette page de Contact est obtenue en utilisant la classe Page pour accomplir l'essentiel du travail nécessaire à la génération de la page

Listing 4. : Plan_du_Site.php - Cette page Plan du Site est obtenue en utilisant la classe Page pour accomplir l'essentiel du travail nécessaire à la génération de la page

Le concept d'héritage nous offre une solution bien meilleure : nous pouvons créer une nouvelle classe qui hérite de l'essentiel de la fonctionnalité de la classe Page, mais qui redéfinit les parties que nous voulons présenter différemment.

Par exemple dans le cas du site C.E.I., nous pourrions vouloir implémenter une seconde barre de navigation dans la page Services.

Le script donné dans le Listing 5 permet d'apporter cette modification, en créant une nouvelle classe appelée Services_Page, qui hérite de la classe Page. Les boutons et les liens que nous voulons voir figurer dans une seconde ligne sont stockés dans un nouveau tableau, appelé $row2_buttons. Parce que cette classe doit avoir un comportement très semblable à celui de la classe Page, nous ne redéfinissons que les parties à modifier, c'est-à-dire l'opération Display().

Listing 5. : Services.php - La classe Services_Page hérite de la classe Page, mais redéfinit l'opération Display() de sorte à produire une barre de navigation différente

L'opération Display() redéfinie est analogue à l'opération Display() de la classe Page, si ce n'est qu'elle contient la ligne supplémentaire suivante :

    $this->Display_Menu($this->row2_buttons) ;

Cette ligne invoque Display_Menu() une seconde fois, de sorte à créer la seconde barre de menus.

Hors de la définition de la classe, nous créons une instance de la classe Services_Page, nous ajustons les valeurs qui requièrent des valeurs différentes des valeurs par défaut, et nous invoquone Display().

Nous mettons à votre disposition les Listings, des pages suivantes :

Electronique.php (Listing 6).

Conformites_aux_Normes.php (Listing 7).

Informatique.php (Listing 8).

Enonces_de_Mission.php (Listing 9).

Information_Legale_Classe.html (Listing 10).

Listing 6. : Electronique.php - La classe Electronique.php hérite de la classe Page, mais redéfinit l'opération Display() de sorte à produire une barre de navigation différente

Listing 7. : Conformites_aux_Normes.php - La classe Conformites_aux_Normes.php hérite de la classe Page, mais redéfinit l'opération Display() de sorte à produire une barre de navigation différente

Listing 8. : Informatique.php - La classe Informatique.php hérite de la classe Page, mais redéfinit l'opération Display() de sorte à produire une barre de navigation différente

Listing 9. : Enonces_de_Mission.php - La classe Enonces_de_Mission.php hérite de la classe Page, mais redéfinit l'opération Display() de sorte à produire une barre de navigation différente

Listing 10. : Information_Legale_Classe.html

Comme le montre la figure ci-dessous, nous produisons bien ainsi une variante de la page standard. Pour cela, nous nous sommes contenté d'écrire du nouveau code pour les seules parties réellement différentes et nous avons rajouté quelques pages pour vos essais de travaux.

La création de pages via des classes PHP présente des avantages indéniables. En disposant d'une classe capable de faire l'essentiel du travail à notre place, la création d'une nouvelle page ne nécessite que très peu d'efforts. De plus, nous pouvons facilement mettre à jour toutes les pages du site en une seule fois, en travaillant directement à la source, c'est-à-dire sur la classe. Grâce au principe de l'héritage, différentes variantes d'une même classe peuvent être aisément obtenues, en conservant les avantages de la classe d'origine.

Comme c'est hélas généralement le cas, les avantages de cette approche ont un coût.

La génération de pages à partir d'un script requiert plus d'effort de la part du processeur de l'ordinateur que le simple chargement d'une page HTML statique à partir d'un disque dur, ou la transmission d'une page à un navigateur. Sur un site très fréquenté, ce point peut se révéler important. L'emploi de pages HTML statiques peut alors être préférable, ou la mise en mémoire cache des scripts, de sorte à réduire autant que possible la charge pesant sur le serveur.

Nous terminons ainsi cette sixième leçon et nous verrons dans la prochaine, l'usage d'une Base de données MySQL, et à exploiter les notions relatives à PHP apprises dans les leçons précédentes pour accéder à une base de données à partir du Web.


Conception de votre Base de Données

Conception de votre base de données Web (1ère partie) :

Concepts des bases de données relationnelles :

Puisque vous connaissez maintenant les éléments essentiels du langage PHP, nous allons nous intéresser à l'intégration d'une base de données dans vos scripts. Dans la deuxième leçon, nous avons présenté les avantages de l'utilisation d'une base de données relationnelle à la place d'un fichier brut. On verra tous ces points concernant des atouts des RDBMS (Relational DataBase Management System) :

Ils permettent d'accéder aux données plus rapidement qu'avec des fichiers bruts.

On peut les interroger très facilement pour récupérer des ensembles de données satisfaisant certains critères.

Ils possèdent des mécanismes intégrés permettant de gérer les accès simultanés, pour que le programmeur, c'est-à-dire vous-même, n'ait pas besoin de s'en occuper.

Ils permettent d'accéder aléatoirement à vos données.

Ils possèdent des systèmes de privilèges intégrés.

Concrètement, l'utilisation d'une base de données relationnelle vous permet rapidement et simplement à des questions comme l'origine de vos clients, vos produits qui se vendent le mieux, ou le type de clients qui dépensent le plus d'argent. Ces informations pourront vous aider à améliorer votre site pour attirer un plus grand nombre d'utilisateurs, et pour les fidéliser. La base de données que nous traiterons dans cette leçon est MySQL.

Les bases de données relationnelles sont, de loin, les bases de données les plus utilisées. Elles font appel à de solides bases théoriques, en algèbre relationnelle. Vous n'avez pas besoin de comprendre cette théorie relationnelle pour pouvoir utiliser une base de données relationnelle (ce qui est fort heureux), mais vous devez, en revanche connaître quelques concepts essentiels des bases de données.

Tableaux :

Les bases de données relationnelles sont composées de "relations", que l'on appelle plus couramment des "tableaux". Un tableau est en fait un ensemble de données organisées d'une certaine manière. Si vous avez déjà utilisé une feuille de calcul dans un tableur, vous avez déjà utilisé un tableau relationnel.

Intéressons-nous à un petit exemple.

Dans la figure 1, vous trouverez un exemple de tableau, qui contient les noms et les adresses des clients d'une librairie, de chez Jean-Pierre.

Ce tableau possède un Nom (Les Clients), un certain nombre de colonnes (correspondant chacune à un type d'information) et plisieurs lignes correspondant aux différents Clients.

Colonnes :

Chaque colonne possède un Nom unique et contient différentes données. De plus, dans le Tableau Les Clients de la figure 1, vous pouvez voir que la colonne Client_ID contient des nombres entiers, alors que les trois autres colonnes contiennent des chaînes de caractères. Les colonnes sont parfois appelées des champs ou des attributs.

Lignes :

Chaque ligne de ce tableau représente un client particulier. Grâce au format de ce tableau, toutes ces lignes possèdent les mêmes attributs. Les lignes peuvent également être appelées des enregistrements ou des tuples.

Valeurs :

Chaque ligne est composée d'un ensemble de valeurs particulières correspondant à chaque colonne. Le type de chaque valeur doit correspondre au type de la colonne dans laquelle elle se trouve.

Clés :

Il nous faut ensuite un moyen d'identifier chaque client. Généralement, les noms des clients ne sont pas très pratiques pour cela. Si vous possédez un nom assez répandu, vous avez probablement déjà compris pourquoi. Prenons par exemple le Nom de Pierre DUPOND dans le tableau Les Clients. En ouvrant un annuaire téléphonique, on se rend aussitôt compte qu'il existe un grand nombre de personnes possédant ce nom.

Nous pouvons identifier l'utilisateur Pierre DUPOND de plusieurs manières. En effet, on peut supposer qu'il s'agit uniquement le seul Pierre DUPOND habitant à son adresse. Cependant, le fait de désigner ce client par "Pierre DUPOND, 75 Rue de Lattre, Paris" est assez pénible et plutôt formel. Cela implique aussi d'utiliser plusieurs colonnes dans le tableau.

Dans cet exemple, nous avons choisi une approche que vous reprendrez probablement dans vos applications : l'affectation d'un identificateur de client unique, Client_ID, à chaque client. Ce principe est assez courant : vous possédez déjà un numéro de compte bancaire unique. Cela permet d'enregistrer les détails vous concernant dans une base de données d'une manière plus efficace et plus simple. de plus, on peut s'assurer que ce numéro d'identification est unique. Dans la pratique, il existe peu d'informations qui possèdent cette propriété, même si on en utilise plusieurs conjointement.

La colonne d'identification d'un tableau est appelé la clé, ou la clé primaire. Une clé peut également être répartie sur plusieurs colonnes. Par exemple, si nous avions choisi d'identifier Pierre avec "Pierre DUPOND, 75 Rue de Lattre, Paris", la clé contiendrait les colonnes Nom, Adresse et Ville, et dans ce cas, il est possible de garantir son unicité.

Les bases de données contiennent en général plusieurs tableaux, et se servent des clés comme d'une référence d'un tableau à un autre. Dans la figure 2, nous avons ajouté un second tableau dans la base de données. Celui-ci contient les commandes effectuées par les clients. Chaque ligne du tableau de Commandes représente une seule commande, effectuée par un seul client. Le client est identifié par le Numéro de Commande_ID valant 2, nous pouvons voir qu'elle a été effectuée par le client dont le Client_ID vaut 1. Si nous nous reportons ensuite au tableau Les Clients, nous pouvons voir que le Client_ID vaut 1 et fait référence à Pierre DUPOND.

Dans la terminologie des bases de données relationnelles, cette relation est appelée une clé externe. Dans le tableau Client_ID est la clé primaire dans le tableau "Les Clients", mais lorsqu'elle apparaît dans un autre tableau, comme le tableau de Commandes, elle devient une clé externe.

Vous vous demandez peut-être pourquoi nous avons choisi d'implémenter deux tableaux différents : pourquoi ne pas se contenter d'enregistrer l'adresse de Pierre DUPOND dans le tableau de Commandes ? C'est ce que nous allons voir dans la prochaine section de cette leçon.

Schémas :

La structure globale des tableaux d'une base de données est appelée le schéma de cette base de données. Il s'agit d'une sorte de plan de la base de données. Un schéma doit représenter les tableaux ainsi que leurs colonnes, le type de données de chaque colonne, et préciser la clé primaire de chaque tableau et toutes les clés externes. Un schéma ne contient aucune donnée, mais vous pouvez choisir de présenter quelques données typiques avec votre schéma pour expliquer son fonctionnement. Un schéma peut être présenté tel qu'il apparaît dans les diagrammes que nous utilisons, dans des diagrammes de relations d'entités (que nous n'aborderons pas dans cette leçon), ou plus simplement dans un format texte, comme ceci :

Les Clients(Client_ID, Nom, Adresse, Ville)

Commandes(Commande_ID, Client_ID, Prix, Date)

Les termes soulignés dans ce schéma sont les clés primaires pour la relation dans laquelle elles sont soulignées. Les termes soulignés en pointillé sont les clés externes pour la relation dans laquelle elles apparaissent soulignées en pointillé.

Relations :

Les clés externes représentent une relation entre les données et les tableaux. Par exemple, le lien du tableau Commandes vers le tableau Les Clients représente une relation entre une ligne du tableau Commandes et une ligne du tableau Les Clients.

Il existe trois principaux types de relations dans une base de données relationnelle. Ces relations peuvent être classées en fonction du nombre d'éléments intervenant dans chaque membre de la relation : un-vers-un, un-vers-plusieurs, ou plusieurs-vers-plusieurs.

Une relation un-vers-un signifie que la relation fait intervenir un seul élément de chaque côté. Par exemple, si nous avions placé les adresses dans un autre tableau que Les Clients, il existerait une relation un-vers-un entre elles. Vous pouvez disposer d'une clé externe de "Adresse" vers Les Clients, ou dans l'autre sens (aucune des deux n'est nécessaire).

Dans une ralation un-vers-plusieurs, une ligne d'un tableau est associée à plusieurs lignes d'un autre tableau. Dans notre exemple, un client référencé dans le tableau "Les Clients" peut effectuer plusieurs commandes, apparaissant dans le tableau "Commandes". Dans ce type de relation, le tableau dont plusieurs lignes participent à la relation possède une clé externe vers l'autre tableau. Dans notre cas, nous avons placé Client_ID dans le tableau de Commandes pour illustrer cette relation.

Dans une relation plusieurs-vers-plusieurs, plusieurs lignes d'un tableau sont associées à plusieurs lignes d'un autre tableau. Par exemple, si nous prenons l'exemple de deux tableaux, "Books" et "Authors", il se peut qu'un livre ait été écrit par deux auteurs, chacun d'entre eux ayant écrit d'autres livres, soit indépendamment, soit avec d'autres auteurs. Ce type de relation est généralement assez complexe, c'est pourquoi, il peut être intéressant de posséder les tableaux "Books", "Authors" et "Books_Authors". Ce dernier tableau ne contient que les clés des autres tableaux sous la forme de clés externes, pour connaître les auteurs associés à chaque livre.

Comment concevoir votre base de données Web :

Lorsque vous créez une base de données, vous modélisez généralement des objets du monde réel et les relations qui existent entre eux, et vous enregistrez des informations sur ces objets et sur ces relations.

Généralement, chaque type d'objet réel que vous modélisez a besoin de son propre tableau. En effet, dans notre exemple, il faut enregistrer les mêmes infomations pour tous les clients. Si un ensemble de données possède les mêmes propriétés, vous pouvez commencer par créer un tableau correspondant à ces données.

Dans l'exemple que nous évoquons de la librairie de chez Jean-Pierre, nous devons enregistrer des informations sur les clients, les livres à vendre, et sur les détails de chaque commande. Tous les clients possèdent un nom et une adresse. Les commandes sont caractérisées par une date, un montant total, et un ensemble de livres achetés. Chaque livre possède un code ISBN, un auteur, un titre, et un prix.

D'après ces caractéristiques, nous pouvons créer au moins trois tableaux dans cette base de données. Les Clients, Commandes et Books. Ce schéma initial est présenté à la figure 3.

Pour l'instant, il est impossible de deviner, à partir du modèle, les livres qui correspondent à chaque commande. Nous allons nous en occuper maintenant.

Evitez d'enregistrer des informations redondantes :

Nous avons déjà posé la question suivante : "Pourquoi ne pas enregistrer l'adresse de Pierre DUPOND dans le tableau de Commandes ?"

Si Pierre achète plusieurs livres chez Jean-Pierre, le responsable, cela reviendrait à enregistrer plusieurs fois les informations le concernant. Au cours du temps, le tableau de Commandes pourrait ressenbler à celui de la figure 4.

Cela pose essentiellement deux problèmes.

Tout d'abord, cette approche gaspille les ressources du système. Pourquoi enregistrer trois fois les données concernant Pierre, alors qu'il suffit de les enregistrer une seule fois ?

Le second problème est que cette approche peut entraîner des anomalies dans les mises à jour des informations, c'est-à-dire des situations dans lesquelles certaines informations de la base de données sont modifiées. Cette dernière se retrouve alors dans un état non cohérent. L'intégrité des données est corrompue, et il est impossible de savoir quelles sont les données correctes, et quelles sont les données incorrectes. Cela entraîne souvent des pertes d'informations.

Il convient d'éviter trois types d'anomalies : les anomalies de modification, d'insertions, et de suppressions.

Si Pierre déménage pendant qu'il a une commande en cours, il faut mettre à jour son adresse à trois endroits au lieu d'un seul, ce qui représente trois fois plus de travail. Il est assez facile d'oublier cette tâche et de ne changer son adresse qu'une seule fois, ce qui entraîne des incohérences dans la base de données (à éviter à tout prix). Ce type de problème est appelé une "anomalie de modification", puisqu'il a lieu pendant une modification de la base de données

Avec cette architecture, nous devons saisir les détails concernant Pierre chaque fois qu'il effectue une commande, et vérifier que ces détails sont cohérents avec les données existant déjà dans le tableau. Si nous oublions cette vérification, il se peut que nous nous retrouvions avec deux lignes contenant des informations différentes sur Pierre. Par exemple, l'une de ces lignes peut indiquer que Pierre Habite à PARIS, et une autre qu'il habite à NANTES. Ce type d'erreur est appelé une "anomalie d'insertion", puisqu'elle a lieu lorsque de nouvelles données sont insérées dans les tableaux.

Le troisième type d'anomalie est appelé "anomalie de suppression", puisque ces anomalies ont lieu lorsque des données sont supprimées dans la base de données. Par exemple, imaginons que lorsqu'une commande est terminée, nous la supprimons de la base de données. Lorsque toutes les commandes de Pierre ont été traitées, elles sont toutes supprimées du tableau de Commandes. Cela signifie que l'adresse de Pierre n'existe plus dans notre base de données. Il est alors impossible de lui envoyer des publicités, et la prochaine fois qu'il souhaitera passer une commande, il faudra rassembler à nouveau tous les détails le concernant.

Les bases de données sont normalement conçues pour qu'aucune de ces anomalies ne puisse avoir lieu.

Choisir des clés cohérentes :

Assurez-vous que les clés que vous choisissez sont uniques. Dans notre cas, nous avons créé des clés particulières pour les clients (Client_ID) et pour les commandes (Commande_ID), puisque ces objets du monde réel ne possèdent pas forcément un identificateur unique. Nous n'avons pas besoin de créer un identificateur unique pour les livres, puisqu'il en existe un : le numéro ISBN. Pour le tableau de Commandes_Articles, vous pouvez éventuellement ajouter une clé supplémentaire, mais la combinaison des deux attributs Commandes_ID et ISBN est unique, tant que plusieurs exemplaires d'un même livre dans une même commande sont traités sur une seule ligne. C'est pour cela que le tableau Commandes_Articles possède une colonne Quantity. Ce qui signifie "quantité".

Pensez aux questions que vous poserez à votre base de données :

Il est primordial de connaître les questions auxquelles la base de données doit pouvoir répondre. Vous pouvez par exemple reprendre les questions que nous avons mentionnées au début de cette leçon. Par exemple, quelles sont les meilleures ventes ? Assurez-vous que votre base de données contient toutes les donnés nécessaires, et que les liens appropriés existent entre les différents tableaux pour répondre correctement à vos questions.

Evitez les architectures multipliant les attributs vides :

Si nous souhaitons ajouter des résumés ou commentaires aux livres de la base de données, nous pouvons choisir entre deux approches différentes. Ces deux approches sont présentées à la figure 6.

La première méthode consiste à ajouter une colonne Résumé dans le tableau Books. De cette manière, il existe un champ Résumé pour chaque livre. Si la base de données contient beaucoup de livres, et si la personne qui rédige les résumés n'a pas l'intention de résumer chaque livre, il se peut que plusieurs lignes ne possèdent aucune valeur associée à cet attribut. On parle dans ce cas de valeurs nulles.

Il faut toujours éviter d'insérer des valeurs nulles dans une base de données. En effet, il s'agit d'un gaspillage de l'espace de stockage et cela peut entraîner divers problèmes lorsque vous calculez des totaux ou d'autres fonctions sur de colonnes numériques. De plus, lorsqu'un utilisateur voit une valeur nulle dans un tableau, il ne peut pas savoir si la valeur de cet attribut n'a aucune signification, s'il s'agit d'une erreur dans la base de données, ou s'il s'agit d'une donnée qui n'a pas encore été saisie.

Une architecture différente permet souvent de ne pas avoir recours à des valeurs nulles. Dans notre cas, nous pouvons avoir recours à la seconde architecture présentée à la figure 6. Dans cette organisation, seuls les livres qui possèdent un résumé sont spécifiés dans le tableau Book_Reviews, avec leur résumé.

Vous remarquerez que cette architecture nécessite un rédacteur de résumés en interne. Il est également possible de permettre aux utilisateurs d'écrire ces résumés. Pour cela, il suffit d'ajouter l'attribut Client_ID dans le tableau Book_Reviews.

Résumé des types de tableaux :

Les bases de données sont généralement composées de deux types de tableaux :

  • Des tableaux simples qui décrivent des objets du monde réel. Ces tableaux peuvent également contenir des clés vers d'autres objets simples, pour lesquels, il existe une relation un-vers-un ou un-vers-plusieurs. Par exemple, un client peut passer plusieurs commandes, mais chaque commande est effectuée par un seul client. Par Conséquent, nous pouvons placer dans chaque commande une référence au client qui a effectué cette commande.

  • Des tableaux de liaison qui décrivent des relations plusieurs-vers-plusieurs entre deux objets réels, comme la relation qui existe entre Commandes, figure 4 et Commandes Articles, figure 5. Ces tableaux sont souvent associés à des transactions réelles.

Architecture d'une base de données Web :

Maintenant que nous avons présenté l'architecture interne de votre base de données, nous pouvons nous intéresser à l'architecture externe des systèmes de bases de données Web, et présenter la méthodologie permettant de développer ces systèmes.

Architecture :

Le fonctionnement fondamental d'un serveur Web est présenté à la figure 7. Ce système est composé de deux objets : un navigateur Web et un serveur Web. Un lien de communication doit exister entre ces deux objets. Le navigateur Web effectue des requêtes auprès du serveur, et le serveur renvoie des réponses. Cette architecture est parfaitement adaptée à un serveur qui fournit des pages statiques. L'architecture qui permet de servir des sites Web faisant intervenir des bases de données est un peu plus complexe.

Les applications de base de données Web que nous allons mettre en œuvre dans cette leçon respectent une structure de base de données Web générale, qui est présentée à la figure 8. L'essentiel de cette structure devrait déjà vous sembler familier.

Une transaction de base de données Web typique est composée des étapes suivantes, qui sont numérotées sur la figure 8. Noua allons examiner ces étapes dans le contexte de la librairie de chez Jean-Pierre.

  1. Le navigateur Web d'un utilisateur envoie une requête HTTP pour une page Web particulière. Par exemple, cette requête peut concerner tous les livres de chez Jean-Pierre écrit par Laura Thomson, et se présente sous la forme d'un formulaire HTML. La page de recherche des résultats est appelée Results.php

  2. Le serveur Web reçoit la requête pour Results.php, récupère le fichier et le passe au moteur PHP afin qu'il soit traité.

  3. Le moteur PHP commence à analyser le script. A l'intérieur de ce script se trouve une commande permettant de se connecter à la base de données et d'exécuter une requête (pour rechercher les livres). PHP ouvre une connexion vers le serveur MySQL, et transmet la requête appropriée.

  4. Le serveur MySQL reçoit la requête de la base de données et la traite, puis renvoie les résultats (c'est-à-dire une liste de livres) au moteur PHP.

  5. Le moteur PHP termine l'exécution du script, ce qui consiste généralement, en un formatage des résultats de la requête en HTML. Il envoie ensuite, le fichier HTML obtenu au serveur Web.

  6. Le serveur Web transmet la page HTML au navigateur, pour que l'utilisateur puisse voir la liste des livres qu'il a recherchés.

Ce processus reste relativement identique, quels que soient le moteur de scripts et le serveur de base de données que vous utilisez. Le plus souvent, le serveur Web, le moteur PHP et le serveur de bases de données sont tous exécutés sur le même ordinateur. Cependant, il arrive que le serveur de base de données soit exécuté sur un autre ordinateur. Cette dernière approche répond à des problèmes de sécurité, d'augmentation des capacités, et de répartition de la charge. Au niveau de développement, cela ne change pas grand chose, bien que cette approche fournisse des avantages significatifs en termes de performances.

Dans cette leçon, nous avons présenté quelques conseils généraux pour l'architecture des bases de données relationnelles. Toutefois, si vous souhaitez vous attaquer plus profondément à la théorie des bases de données relationnelles, vous pouvez consulter plusieurs ouvrages écrits par des auteurs faisant référence à nos leçons, comme C.J Date. Cependant, vous devez savoir que ces ouvrages sont très théoriques, et n'ont pas nécessairement d'intérêt immédiat pour un développeur Web commercial. Généralement, les bases de données Web classiques ne sont pas très compliquées.

Nous terminons ainsi cette septième leçon et nous verrons dans la prochaine, l'usage que nous nous intéresserons à la Construction de votre Base de données MySQL ainsi que la création des bases de données et des utilisateurs.


Identificateurs MySQL

Conception de votre base de données Web (4ème partie) :

Identificateurs MySQL :

Il existe quatre types d'identificateurs dans MySQL : les bases de données, les tableaux et les colonnes, que nous connaissons déjà, et les alias, que nous étudierons au prochain chapitre.

Dans la structure interne de MySQL, les bases de données sont associées à des dossiers, et les tableaux à des fichiers. Cette implémentation a un effet direct sur les noms que vous pouvez leur donner. Elle influe également sur les majuscules et les minuscules dans ces noms : si votre système d'exploitation respecte les majuscules et les minuscules dans les noms des dossiers et des fichiers, les noms des bases de données et des tableaux respecteront également les majuscules et les minuscules (par exemple, sous Unix). En revanche, Windows ne respecte pas les majuscules et les minuscules dans les noms de fichiers. Les noms des colonnes et les noms des alias ne respectent pas les majuscules et les minuscules, mais, il est cependant impossible d'utiliser différentes syntaxes d'un même nom dans une même instruction SQL.

De plus, l'emplacement des dossiers et des fichiers contenant vos données dépend de votre configuration. Vous pouvez vérifier cet emplacement, en utlisant mysqladmin :

    mysqladmin variables

Le tableau 4 présente un résumé des différents identificateurs. Il faut également savoir qu'il est impossible d'utiliser les caractères ASCII 0 et 255 dans les identificateurs (ces caractères sont rarement utiles).

Tableau 4. - Identificateurs MySQL :
Type | Longueur maximale | Majuscules / Minuscules | Caractères autorisés
Bases de données | 64 | Comme l'O / S | N'importe quel caractère autorisé dans les noms des dossiers par votre système d'exploitation, sauf le caractère /.
Tableau | 64 | Comme l'O / S | N'importe quel caractère autorisé dans les noms des fichiers de votre système d'exploitation, sauf les caractères / et .
Colonne | 64 | Non | N'importe lesquels.
Alias | 255 | Non | N'importe lesquels.

Ces règles sont extrêmement flexibles.

Avec MySQL et selon les versions, les identificateurs peuvent également contenir des mots réservés, ou n'importe quel caractère particulier, la seule limitation étant que si vous utilisez cette caractéristique, il faut placer vos identificateurs entre guillemets simples inversés (Alt Gr + è).

Par exemple :

    create database `create database` ;

Dans les versions précédentes de MySQL 3, ces règles sont plus restrictives et ne permettent pas ce genre de manipulation.

Naturellement, cette liberté supplémentaire ne doit être utilisée qu'à bon escient. Ce n'est pas parce que vous pouvez choisir n'importe quel nom qu'il faut le faire systématiquement. Ce principe est aussi valable dans n'importe quel type de programmation : il faut toujours utiliser des identificateurs dont le nom est significatif.

Types de données des colonnes :

MySQL reconnaît trois principaux types de données dans les colonnes : des valeurs numériques, des dates et des heures, et des chaînes de caractères. Dans chacune de ces catégories, il existe plusieurs types différents. Nous allons maintenant les passer en revue, et nous verrons dans les prochaines leçons leurs avantages et leurs inconvénients.

Il existe plusieurs variantes de ces types, en fonction de leur taille de stockage. Lorsqu'on choisit un type de colonne, il faut généralement choisir le type le plus petit dans lequel vos données peuvent entrer.

Pour plusieurs types de données, lorsque vous créez une colonne, vous pouvez spécifier la longueur maximale d'affichage (qui correspond au paramètre M dans les tableaux suivants). Ci ce paramètre est optionnel, il est spécifié entre crochets. La valeur maximale de M est 255.

Dans les descriptions suivantes, les valeurs optionnelles sont présentées entre crochets.

Types numériques :

Les types numériques sont soit des nombres entiers, soit des nombres à virgule flottante. Pour les nombres à virgule flottante, vous pouvez spécifier le nombre de chiffre après la virgule (paramètre D). La valeur maximale de D est la plus petite valeur entre 30 et M-2, (c'est-à-dire, la longueur maximale d'affichage moins deux, un caractère pour le point et un pour la partie entière du nombre).

Pour les types entiers, vous pouvez spécifier l'attribut UNSIGNED, pour accepter uniquement des nombres positifs, comme le montre le Listing 1 à cette adresse, en cliquant ici.

Pour tous les types numériques, vous pouvez spécifier l'attribut ZEROFILL. Lorsque les valeurs d'une colonne ZEROFILL sont affichées, elles sont justifiées à gauche avec des 0.

Les types entiers sont présentés dans le tableau 5. Vous remarquerez que, dans ce tableau, nous fournissons à la fois les intervalles signés et non signés.

Tableau 5. - Types de données entiers :
Type | Intervalle | Taille (octets) | Description
TINYINT [(M)] | -127 ... 128 ou 0 ... 255 | 1 | Entiers très courts
SMALLINT [(M)] | - 32 768 ... 32 767, ou 0 ... 65 535 | 2 | Entiers courts
MEDIUMINT [(M)] | - 8 388 608 ... 8 388 607, ou 0 ... 16 777 215 | 3 | Entiers de taille moyenne
INT [(M)] | - 231 ... 231 - 1, ou 0 ... 232 - 1 | 4 | Entiers classiques
INTEGER [(M)] |  |  | Synonyme de INT
BIGINT [(M)] | - 263 ... 263 - 1, ou 0 ... 264 - 1 | 8 | Entiers larges

Les types à virgule flottante sont présentés dans le tableau 6.

Tableau 6. - Types de données à virgule flottante :
Type | Intervalle | Taille (octets) | Description
FLOAT (précision) | Dépend de la précision | Varie | Peut être utilisé pour spécifier des nombres à virgule flottante en simple ou en double précision.
FLOAT [(M, D)] | ± 1.175494351E-38, ± 3.402823466E+38 | 4 | Nombres à virgule flottante en simple précision. Équivalent à FLOAT(4), en spécifiant une largeur d'affichage et un nombre de chiffres après la virgule.
DOUBLE [(M, D)] | ± 1.7976931348623157E+308, ± 2.2250738585072014E-308 | 8 | Nombres à virgule flottante en double précision. Équivalent à FLOAT(8), en spécifiant une largeur d'affichage et un nombre de chiffres après la virgule.
DOUBLE PRECISION [(M, D)] |  |  | Synonyme de DOUBLE [(M, D)].
REAL [(M, D)] | Comme ci-dessus |  | Synonyme de DOUBLE [(M, D)].
DECIMAL [(M[,D])] | Varie | M + 2 | Nombres à virgule flottante enregistrés dans des char. L'intervalle dépend de M, la largeur d'affichage.
NUMERIC [(M, D)] | Comme ci-dessus |  | Synonyme de DECIMAL.

Types de dates et d'heures :

MySQL supporte plusieurs types de dates et d'heures, qui sont présentés dans le tableau 7. Avec tous ces types, vous pouvez saisir vos données sous la forme d'une chaîne de caractères ou sous un format numérique. Vous devez en outre savoir qu'une colonne TIMESTAMP d'une ligne particulière prend automatiquement la date et l'heure de la dernière opération sur cette ligne, si vous ne la définissez pas manuellement. Cette caractéristique est très utile pour conserver une trace des transactions.

Tableau 7. - Types de dates et d'heures :
Type | Intervalle | Description
DATE | 2000-01-01, 2016-12-31 | Une date, affichée au format YYYY- MM - DD.
TIME | -838:59:59, 838:59:59 | Une heure, affichée au format HH: MM:SS. Vous remarquerez que cet intervalle est beaucoup plus grand que ce que l'on utilise ordinairement.
DATETIME | 2000-01-01 00:00:00, 1999-12-31 23:59:59 | Une date et une heure, affichées au format YYYY - MM - DD HH:MM:SS.
TIMESTAMP [(M)] | 1980-01-01 00:00:00 | Une date complète (ou timbre à date), utile pour identifier les transactions. Le format d'affichage dépend de la valeur de M (voir le Tableau 8).
 | Parfois en 2039 | La valeur maximale dépend de la limite d'Unix.
YEAR [(2 | 4)] | 70-89 (1980 -2070), 1901-2155 | Une année, au format de 2 ou 4 chiffres. Un intervalle différent correspond à chacun de ces formats.

Le Tableau 8 présente les différents types d'affichage de TIMESTAMP :

Tableau 8. - Les types d'affichage de TIMESTAMP :
Type Spécifié | Affichage
TIMESTAMP | YYYYMMDD HHMMSS
TIMESTAMP (14) | YYYYMMDD HHMMSS
TIMESTAMP (12) | YYMMDD HHMMSS
TIMESTAMP (10) | YYMMDD HHMM
TIMESTAMP (8) | YYYYMMDD
TIMESTAMP (6) | YYMMDD
TIMESTAMP (4) | YYMM
TIMESTAMP (2) | YY

Types de chaînes :

Il existe trois grands types de chaînes. Tout d'abord, il y a des chaînes classiques, c'est-à-dire des chaînes de texte brut. Ces chaînes correspondent aux types CHAR (longueur fixe) et VARCHAR (longueur variable). Vous pouvez spécifier la largeur de ces chaînes. Les colonnes de type CHAR sont justifiées avec des espaces, quelle que soit la taille des données d'origine, alors que les colonnes VARCHAR sont ajustées en largeur, automatiquement en fonction des données. Vous remarquerez que MySQL supprime les espaces ajoutés aux CHAR lorsqu'ils sont lus, et ceux des VARCHAR lorsqu'ils sont enregistrés. Il existe une fois de plus un compromis entre ces deux types, au niveau de la place mémoire et de la rapidité. Nous y reviendrons dans la prochaine leçon.

Il existe aussi les types TEXT et BLOB, dans différentes tailles. Ces types correspondent à des données texte ou binaire, plus longues. Les BLOB sont des "objets binaires de taille importante" (Binay Large OBjects). Ils peuvent contenir tout ce que vous voulez, comme des images ou des sons.

Dans la pratique, les colonnes BLOB et TEXT sont identiques, sauf que les colonnes TEXT respectent les majuscules et les minuscules, contrairement aux colonnes BLOB. Comme ces types de colonnes peuvent contenir des données très volumineuses, ils nécessitent certaines précautions. Nous les reverrons dans les prochains chapitres.

Le troisième groupe contient deux types spéciaux, SET et ENUM. Le type SET est utilisé pour spécifier les valeurs de cette colonne qui doivent provenir d'un ensemble particulier de valeurs. Les valeurs de la colonne peuvent contenir plusieurs valeurs provenant de cet ensemble. Vous pouvez avoir au maximum 64 éléments provenant de l'ensemble spécifié.

ENUM est un type d'énumération, qui est très semblable à SET, sauf que les colonnes de ce type ne peuvent contenir qu'une seule des valeurs spécifiées, ou NULL, et vous ne pouvez pas placer plus de 65 535 éléments dans une énumération.

Nous avons résumé les types de chaînes dans les Tableaux 9, 10, et 11. Le Tableau 9 présente les types de texte brut.

Le Tableau 10 résume les types TEXT et BLOB. La longueur maximale d'un champ TEXT (en caractères) correspond à la taille maximale, en octets des fichiers qui doivent être enregistrés dans ce champ.

Le Tableau 11 présente les types ENUM et SET.

Tableau 9. - Types de chaînes classiques :
Type | Intervalle | Description
[NATIONAL] CHAR (M) [BINARY] | 1 à 255 | Chaîne de taille fixe, de longueur M, où M est compris entre 1 à 255. Le mot clé NATIONAL spécifie que le jeu de caractères par défaut doit être utilisé. Cela correspond au comportement par défaut de MySQL, mais il peut également être spécifié parce qu'il fait partie du standard SQL ANSI. Le mot clé BINARY spécifie que les données doivent être traitées en respectant les majuscules et les minuscules (le comportement par défaut est d'ignorer la casse).
[NATIONAL] VARCHAR (M) [BINARY] | 1 à 255 | Comme ci-dessus, sauf que la longueur est variable.

Tableau 10. - Types TEXT et BLOB :
Type | Longueur maximale (caractères) | Description
TINYBLOB | 28 - 1 (c'est-à-dire 255) | Un petit champ BLOB.
TINYTEXT | 28 - 1 (c'est-à-dire 255) | Un petit champ TEXT.
BLOB | 216 (c'est-à-dire 65 535) | Un champ BLOB de taille normale.
TEXT | 216 - 1 (c'est-à-dire 65 535) | Un champ TEXT de taille normal.
MEDIUMBLOB | 224 - 1 (c'est-à-dire 16 777 215) | Un champ BLOB de taille moyenne.
MEDIUMTEXT | 224 - 1 (c'est-à-dire 16 777 215) | Un champ TEXT de taille moyenne.
LONGBLOB | 232 - 1 (c'est-à-dire 4 294 967 295) | Un champ BLOB de grande taille.
LONGTEXT | 232 - 1 (c'est-à-dire 4 294 967 295) | Un champ TEXT de grande taille.

Tableau 11. - Types SET et ENUM :
Type | Maximum de valeurs dans l'ensemble | Description
ENUM ('valeur1' , 'valeur 2' , ...) | 65 535 | Les colonnes de ce type ne peuvent contenir qu'une seule des valeurs listées, ou NULL.
SET ('valeur1' , 'valeur 2' , ...) | 64 | Les colonnes de ce type peuvent contenir un ensemble de valeurs spécifiées, ou NULL.

Pour plus d'informations, vous pouvez vous reporter au chapitre concernant la configuration d'une base de données du manuel en ligne (en anglais), sur le site, en cliquant ici.

Maintenant que vous savez comment créer des utilisateurs, des bases de données et des tableaux, vous pouvez vous consacrer à l'interaction avec la base de données.

Nous terminons cette huitième leçon et nous verrons dans la prochaine, Comment placer des données dans des tableaux, comment les mettre à jour, comment les supprimer, et comment interroger votre base de données.


Recupérer - Groupement - Agrégation - Enregistrements DB

Travailler avec votre base de données MySQL (3ème partie) :

Récupérer les données dans un ordre particulier :

Si vous souhaitez afficher les lignes renvoyées par une requête dans un ordre particulier, vous pouvez vous servir de la clause ORDER BY de l'instruction SELECT. Cela permet de présenter la sortie obtenue dans un format plus lisible.

La clause ORDER BY est utilisée pour trier les lignes en fonction de plusieurs colonnes, listées dans la clause SELECT. Par exemple :

    SELECT nom, adresse

    FROM les_clients

    ORDER BY nom ;

Cette requête renvoie les noms et les adresses des clients, en les triant par ordre alphabétique (sur les noms), comme ceci :

Vous remarquerez que, dans ce cas, comme les noms sont au format Prénom, Nom de famille, ils sont triés en fait d'après le Prénom. Si vous souhaitez les trier d'après le nom de famille, il faut séparer les prénoms et les noms de famille, et les mettre dans deux champs différents.

Par défaut, l'ordre de tri est croissant. Vous pouvez le spécifier explicitement à l'aide du mot clé ASC :

    SELECT nom, adresse

    FROM les_clients

    ORDER BY nom ASC ;

Mais il est également possible de trier par ordre décroissant, en spécifiant le mot clé DESC :

    SELECT nom, adresse

    FROM les_clients

    ORDER BY nom DESC ;

Vous pouvez aussi trier sur plusieurs colonnes, ou vous servir des alias des colonnes, ou même de leur position dans le tableau, (par exemple 3 correspond à la troisième colonne du tableau) au lieu de leur nom.

Par exemple cette requête ci-après :

    SELECT * FROM les_clients WHERE client_id = 3 ;

Groupement et agrégation des données :

Il faut souvent déterminer le nombre de lignes qui appartiennent à un ensemble particulier, ou la valeur moyenne d'une colonne (par exemple, le montant moyen des commandes). MySQL possède plusieurs fonctions d'agrégation qui se révèlent très utiles pour répondre à ce type de requêtes.

Ces fonctions d'agrégation peuvent être appliquées à un tableau pris comme un ensemble, ou à un groupe de données dans un tableau.

Les fonctions d'agrégation le plus utilisées sont présentées dans le Tableau 3.

Tableau 3. - Les fonctions d'agrégation de MySQL :
Nom | Description
AVG (column) | Moyenne des valeurs dans la colonne spécifiée.
COUNT (items) | Si vous spécifiez une colonne, cette fonction renvoie le nombre de valeurs NON NULL dans cette colonne. Si vous ajoutez le mot DISTINCT devant le nom de la colonne, vous obtiendrez le nombre de valeurs distinctes dans cette colonne uniquement. Si vous spécifiez COUNT (*), vous obtiendrez un compte global, indépendamment des valeurs NULL.
MIN (column) | Minimum des valeurs dans la colonne spécifiée.
MAX (column) | Maximum des valeurs dans la colonne spécifiée.
STD (column) | Écart type des valeurs dans la colonne spécifiée.
STDDEV | Comme STD (column).
SUM (column) | Somme des valeurs dans la colonne spécifiée.

Voyons maintenant quelques exemples, en commençant par celui que nous avons mentionné plus haut. Nous pouvons calculer la moyenne des commandes comme ceci :

    SELECT AVG (montant)

    FROM les_commandes ;

Ce qui fournit la sortie suivante :

Pour obtenir des informations plus détaillées, nous pouvons nous servir de la clause GROUP BY. Cela nous permet d'afficher la moyenne des commandes pour différents groupes (par exemple, en fonction du numéro de client). Grâce à ce mécanisme, nous pouvons connaître le client qui a dépensé le plus d'argent :

    SELECT client_id, AVG (montant)

    FROM les_commandes

    GROUP BY client_id ;

Lorsque vous utilisez la clause GROUP BY avec une fonction d'agrégation, elle modifie le comportement de la fonction. Au lieu de fournir la moyenne des montants des commandes dans l'intégralité du tableau, cette requête fournit la moyenne des montants des commandes pour chaque client (ou, plus précisément, pour chaque client_id, ce qui donne un aperçu comme ci-après :

La Valeur Moyenne des Montants des Commandes de chaque Client.png

Un commentaire sur l'utilisation du groupement et des fonctions d'agrégation : en SQL AINSI, si vous utilisez une fonction d'agrégation ou une clause GROUP BY, les seules choses qui peuvent apparaître dans votre clause SELECT sont les fonctions d'agrégation et les colonnes spécifiées dans la clause GROUP BY. De plus, si vous voulez utiliser une colonne dans une clause GROUP BY, elle doit être spécifiée dans la clause SELECT.

MySQL est en fait un peu plus souple. Il supporte une syntaxe étendue, qui permet de ne pas spécifier des éléments dans la clause SELECT si vous ne souhaitez pas les mettre dans ce dernier.

En plus, de regrouper et d'agréger des données, nous pouvons tester le résultat d'une agrégation à l'aide d'une clause HAVING. Elle doit être spécifiée aussitôt après la clause GROUP BY, et elle fonctionne comme une clause WHERE qui ne s'appliquerait qu'aux groupes et aux agrégats.

Pour poursuivre notre exemple précédent, si nous voulons connaître les clients dont la moyenne des commandes est supérieure à 50 euros, nous pouvons nous servir de la requête suivante :

    SELECT client_id, AVG (montant)

    FROM les_commandes

    GROUP BY client_id

    HAVING AVG (montant) > 50 ;

La clause HAVING s'applique aux groupes. Cette requête renvoie le résultat suivant :

Montant superieur a 50 euros.png

Choisir les lignes à renvoyer :

Une clause de l'instruction SELECT qui peut être particulièrement utile dans les applications Web et la clause LIMIT. Elle est utilisée pour spécifier les lignes du résultat qui doivent être renvoyées. Elle accepte deux paramètres : le numéro de ligne de départ et le nombre de ligne à renvoyer.

La requête suivante met en œuvre la clause LIMIT :

    SELECT nom

    FROM les_clients

    LIMIT 2, 3 ;

Ce qui donne ceci :

Cette requête peut être interprétée ainsi : "Sélectionne les noms des clients, et renvoie 3 lignes à partir de la deuxième ligne de la sortie." Vous remarquerez que les lignes sont numérotées à partir de 0, c'est-à-dire que la première ligne de la sortie est la ligne 0.

Cela est très utile pour les applications Web, pour permettre aux clients qui parcourent le catalogue des produits d'afficher uniquement 10 articles par page.

Mise à jour des enregistrements de la base de données :

En plus d'aller chercher des données dans la base de données, il faut souvent les modifier. Par exemple, nous pouvons avoir besoin d'augmenter le prix des livres dans la base de données. Pour cela, il existe l'instruction UPDATE.

Voici le format général d'une instruction UPDATE :

    UPDATE Nom_du_Tableau

    SET column_1 = expression_1, column_2 = expression_2, ...

    [WHERE condition]

    [LIMIT nombre]

Cette instruction met à jour le tabelau appelé Nom_du_Tableau, en modifiant toutes les colonnes spécifiées en fonction des expressions fournies. Vous pouvez restreindre une instruction UPDATE à certaines lignes avec une clause WHERE, et limiter le nombre total de lignes affectées avec une clause LIMIT.

Passons maintenant à quelques exemples.

Si nous souhaitons augmenter tous les prix de 10%, nous pouvons utiliser une instruction UPDATE sans la clause WHERE :

    UPDATE les_livres

    SET prix = prix * 1.1 ;

Si d'un autre côté nous souhaitons modifier une seule ligne (par exemple, pour changer l'adresse d'un client), nous pouvons nous servir de la requête suivante :

    UPDATE les_clients

    SET adresse = '250 rue de Paradis'

    WHERE client_id = 6 ;

Cette requête renvoie le résultat suivant :

Modification des tableaux après leur création :

En plus de mettre à jour le contenu d'un tableau, nous pouvons modifier sa structure. Pour cela, nous pouvons avoir recours à l'instruction ALTER TABLE. Voici son format général :

    ALTER TABLE Nom_du_Tableau alteration [, alteration ...]

Notez que, en SQL ANSI, il n'est possible d'apporter qu'une seule modification par instruction ALTER TABLE, mais avec MySQL, vous pouvez en faire autant que vous le souhaitez. Chaque clause de modification peut être utilisée pour modifier différents aspects du tableau.

Les différents types de modification que vous pouvez apporter avec cette instruction sont présentés dans le Tableau 4.

Tableau 4. - Les modifications possibles avec l'instruction ALTER TABLE :
Syntaxe | Description
ADD [COLUMN] column_description [ FIRST | AFTER column ] | Ajoute une nouvelle colonne à l'emplacement spécifié (s'il n'est pas spécifié, la colonne est ajoutée à la fin). Notez que column_descriptions nécessite un nom et un type, tout comme une instruction CREATE.
ADD [COLUMN] (column_description, column_description, ...) | Ajoute une ou plusieurs colonnes à la fin du tableau.
ADD INDEX [index] (column, ...) | Ajoute un index dans le tableau, sur les colonnes spécifiées.
ADD PRIMARY KEY (column, ...) | Transforme les colonnes spécifiées en clé primaire du tableau.
ADD UNIQUE [index] (column, ...) | Ajoute un index unique dans le tableau, sur les colonnes spécifiées.
ALTER [COLUMN] column {SET DEFAULT VALUE | DROP DEFAULT} | Ajoute ou supprime une valeur par défaut pour une colonne particulière.
CHANGE [COLUMN] column new_column_description | Modifie la colonne spécifiée, en lui affectant la nouvelle description. Vous pouvez vous en servir pour modifier le nom d'une colonne, puisque la description d'une colonne contient son nom.
MODIFY [COLUMN] column_description | Comme CHANGE. Peut être utilisé pour modifier le type d'une colonne, et non son nom.
DROP [COLUMN] column | Supprime la colonne spécifiée.
DROP PRIMARY KEY | Supprime l'index principal (mais pas la colonne).
DROP INDEX index | Supprime l'index spécifié.
RENAME [AS] new_table_name | Renomme un tableau.

Voyons maintenant quelques utilisations courantes de ALTER TABLE.

Il arrive assez souvent que l'on se rende compte qu'une colonne n'est pas assez grande pour les données qu'elle contient. Par exemple, dans notre tableau les_clients, nous avons choisi des noms de 30 caractères au maximum. Après avoir ajouté quelques données, il se peut que nous nous rendions compte que certains noms font plus de 30 caractères, et qu'ils sont tronqués. Pour corriger ce problème, il suffit de modifier le type de la colonne et de choisir une largeur de 45 caractères :

    ALTER TABLE les_clients

    MODIFY nom CHAR(45) NOT NULL ;

Il arrive aussi que l'on ait besoin d'ajouter une colonne. Imaginons par exemple qu'une taxe sur les livres soit ajoutée, et que chez Jean-Pierre ait besoin d'ajouter le montant de cette taxe au total des commandes. Nous pouvons ajouter une colonne taxe dans le tableau les_commandes, comme ceci :

    ALTER TABLE les_commandes

    ADD taxe FLOAT (6,2) AFTER montant ;

Ce qui donne un aperçu ci-après :

Taxe Ajoutee Alter Table_les_Commandes.png

Il se peut aussi que vous ayez besoin de supprimer une colonne. Pour cela, servez-vous de la requête suivante :

    ALTER TABLE les_commandes

    DROP taxe ;

Supprimer des enregistrements dans la base de données :

La suppression des lignes est très simple. Vous pouvez vous servir de l'instruction DELETE, qui ressemble généralement à ceci :

     DELETE FROM table

    [WHERE condition] [LIMIT nombre]

Si vous écrivez uniquement : (Soyez prudent !)

    DELETE FROM table

Toutes les lignes du tableau seront supprimées ! En général, on préfère supprimer certaines lignes, que vous pouvez spécifier dans la clause WHERE. Par exemple, il faut supprimer une ligne si un livre n'est plus disponible, ou si un client n'a passé aucune commande depuis un certain temps, auquel cas, il doit être supprimé de la base de données :

    DELETE FROM les_commandes

    WHERE les_commandes_id = 6 ;

La clause LIMIT peut être utilisée pour limiter le nombre maximal de lignes à supprimer.

Supprimer des tableaux :

Il peut aussi arriver que vous souhaitiez supprimer un tableau de votre base de données. Vous pouvez le faire à l'aide de l'instruction DROP TABLE. Cette instruction est très simple, et elle ressemble à ceci :

    DROP TABLE table ;

Elle supprime toutes les lignes du tableau, et le tableau lui-même. Il convient donc de faire attention lorsque vous l'utilisez.

Supprimer une base de données entière :

Vous pouvez même supprimer l'intégralité d'une base de données avec l'instruction DROP DATABASE, dont la syntaxe ressemble à ceci :

    DROP DATABASE database ;

Elle supprime toutes les lignes, tous les tableaux, tous les index, et la base de données elle-même. Il va donc sans dire qu'elle doit être utilisée avec précaution !

Dans ces trois premiers chapitres de cette leçon, nous avons présenté les opérations les plus courantes de SQL, que vous utiliserez pour interagir avec une base de données MySQL. Dans les deux prochaines leçons, nous verrons comment connecter MySQL et le PHP, pour que vous puissiez accéder à votre base de données à partir du Web. Nous explorerons également quelques techniques avancées de MySQL.

Si vous souhaitez vous documenter plus précisément sur SQL, vous pouvez vous reporter au standard SQL ANSI, en anglais, disponible sur le site fort bien utile également, en cliquant ici.

Nous terminons ainsi cette neuvième leçon et nous verrons dans la prochaine, Comment rendre la base de données de chez Jean-Pierre disponible sur le Web.


Ajouter des Informations dans la Base de Données

Accéder à votre base de données MySQL à partir du Web (2ème partie) :

Ajouter des informations dans la base de données :

L'insertion de nouveaux éléments dans la base de données ressemble beaucoup à leur lecture. Il faut en effet suivre les mêmes étapes : établir une connexion, envoyer une requête et vérifier les résultats. Dans ce cas, vous devez envoyer une requête INSERT INTO au lieu d'une requête SELECT.

Bien que le code soit relativement similaire, il peut être utile de consulter un exemple de référence. La figure 3, vous trouverez un petit formulaire HTML permettant d'ajouter de nouveaux livres dans la base de données.

Le code HTML correspondant à cette page est présenté dans le Listing 4.

Listing 4. - Catalogue_des_Commandes.html - Le code HTML de la page d'ajout de livres :

Les résultats de ce formulaire sont passés aux Resultats_Commandes.php, un script qui s'occupe des détails, effectue quelques validations mineures, et tente d'écrire les informations dans la base de données. Le code de ce script se trouve dans le Listing 5.

Listing 5. - Resultats_Commandes.php - Le script qui écrit les nouveaux livres dans la base de données :

Le résultat d'une insertion réussie est présenté à la figure 4.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2]. - Enregistrement des Informations dans la base de données.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2 bis]. - Lecture des Informations dans la base de données.

Si vous examinez le code de Resultats_Commandes.php, vous constaterez qu'il ressemble au script que nous avons écrit pour lire les informations de la base de données. Nous vérifions que tous les champs du formulaire sont correctement remplis, et nous les formatons pour qu'ils puissent être ajoutés dans la base de données avec addslashes().

    $isbn = addslashes($isbn) ; // Ajoute des anti-slash dans une chaîne

    $auteur = addslashes($auteur) ;

    $titre = addslashes($titre) ;

    $prix = doubleval($prix) ;

Comme le prix de chaque livre est enregistré dans la base de données sous la forme d'un nombre à virgule flottante, il ne doit contenir aucun slash. Nous pouvons filtrer ce caractère et tous les autres caractères gênants avec doubleval(), que nous avons vu dans la leçon 1, en cliquant ici. (Du premier au cinquième chapitre concernant les révisions). Cela permet en outre, de supprimer tous les symboles monétaires que l'utilisateur aurait pu saisir.

Une fois encore, nous nous sommes connecté à la base de données avec mysql_connect(), et nous avons mis en place une requête à envoyer à la base de données. Dans ce cas, il s'agit d'une requête SQL INSERT :

    require ("Connexion_MySQL.php") ;

    $query = "INSERT INTO les_livres VALUES

             ('" . $isbn . "', '" . $auteur . "', '" . $titre . "', '" . $prix . "')" ;

    $Result = mysql_query($query) ;

Cette requête est exécutée sur la base de données d'une manière classique, en appelant mysql_query().

La seule différence significative entre l'utilisation de INSERT et de SELECT réside dans l'utilisation de mysql_affected_rows() :

    echo mysql_affected_rows() . "Livre ins&eacute;r&eacute; dans la base de donn&eacute;es." ;

Dans le script précédent du Listing 2, (en cliquant ici), nous nous sommes servi de mysql_num_row() pour déterminer le nombre de lignes renvoyées par SELECT. Lorsque vous écrivez des requêtes qui modifient la base de données, comme INSERT, DELETE ou UPDATE, vous devez vous servir de mysql_affected_rows().

Nous connaissons maintenant les principales manières d'utiliser des bases de données MySQL à partir du PHP. Nous allons donc nous intéresser aux autres fonctions utiles, que nous n'avons pas encore vues.

Autres fonctions utiles de PHP / MySQL :

Libération des ressources :

Si vous avez des problèmes de mémoire lors de l'exécution d'un script, vous pouvez utiliser mysql_free_result(). Voici le prototype de cette fonction :

    int mysql_free_result(int result) ;

Il faut l'appeler avec un identificateur de résultat, comme ceci :

    mysql_free_result($result) ;

Cette fonction libère la mémoire utilisée pour enregistrer les résultats. Naturellement, il ne faut pas l'appeler tant que vous n'avez pas fini de travailler sur vos résultats.

Création et suppression de bases de données :

Pour créer une nouvelle base de données MySQL à partir d'un script PHP, vous pouvez utiliser mysql_create_db(), et mysql_drop_db() pour la supprimer.

Voici les prototypes de ces fonctions :

    int mysql_create_db(string database, [int database_connection] ) ;

    int mysql_drop_db(string database, [int database_connection] ) ;

Ces deux fonctions prennent en argument un nom de base de données et optionnellement une connexion. Si vous ne spécifiez aucune connexion, la dernière connexion ouverte est utilisée. Ces fonctions renvoient true en cas de succès, et false en cas d'échec.

Nous terminons ainsi cette dixième leçon et nous verrons dans la prochaine, Comment implémenter un contrôle d'accès et autres.


Ajouter des Informations dans la Base de Données

Implémenter une authentification avec PHP et MySQL :

Identification des visiteurs :

Cette leçon explique comment implémenter différentes techniques d'authentification des utilisateurs, à l'aide de PHP et de MySQL.

Le Web est un support relativement anonyme, mais il est souvent intéressant de savoir qui visite votre site. Heureusement pour la confidentialité des utilisateurs, il n'est possible de deviner que peu d'informations personnelles sans leur accord explicite des Internautes.

Avec un peu de travail, les serveurs peuvent déterminer plusieurs informations sur les ordinateurs et les réseaux qui tentent de s'y connecter. Les navigateurs Web ont l'habitude de s'identifier, en fournissant aux serveurs leur nom, leur numéro de version et le nom de votre système d'exploitation. Vous pouvez également déterminer la résolution et le nombre de couleurs de l'écran de vos visiteurs, ainsi que la largeur de leur écran de navigateur.

Chaque ordinateur connecté à Internet possède une adresse IP (Internet Protocole) qui lui est propre. A partir de l'adresse IP d'un visiteur, vous pouvez découvrir certaines informations le concernant. Il est ainsi possible de savoir qui possède une adresse IP, et avec un peu de chance et quelques suppositions, à quel endroit cette personne se trouve. Certaines adresses sont plus utiles que d'autres. Généralement, les personnes disposant d'une connexion permanente à Internet possèdent une adresse IP permanente. En revanche, les personnes qui doivent se connecter par modem à leur fournisseur d'accès Internet (FAI) pour ouvrir chaque session se voient affecter temporairement l'une des adresses IP de leur fournisseur. La prochaine fois que vous verrez une adresse de ce genre, il est fort probable qu'elle appartienne à un autre ordinateur.

Heureusement pour les utilisateurs du Web, aucune des informations fournies par leur navigateur ne permet de les identifier. Si vous souhaitez connaître le nom (ou d'autres détails personnels) d'un utilisateur, vous devrez le lui demander.

Plusieurs sites Web obligent, ou tout du moins encouragent fortement, leurs utilisateurs à fournir ces détails. Ainsi, certains sites proposent gratuitement le contenu de son journal, mais uniquement pour les personnes qui acceptent d'indiquer leur nom, leur sexe et leur revenu global. Certains sites d'informations et de discussions pour informaticiens, permet aux utilisateurs inscrits de participer à des discussions sous un pseudonyme et de personnaliser l'interface de leur site. La plupart des sites de commerce électronique enregistrent les détails de leurs clients lors de leur premier enregistrement. Cela signifie que les clients n'ont pas besoin de saisir à nouveau tous ces détails lors de leurs visites ultérieures.

Après avoir demandé et reçu les informations concernant l'un de vos visiteurs, vous avez besoin d'un moyen d'associer ces informations au même utilisateur la prochaine fois qu'il viendra sur votre site. Si vous partez de l'hypothèse qu'une seule personne visite votre site avec un compte donné, et que chaque visiteur ne se sert que d'un seul ordinateur, vous pouvez enregistrer un cookie sur l'ordinateur de cette personne pour l'identifier avec son accord. Ces suppositions ne sont certainement pas vraies pour tout le monde, puisqu'il arrive souvent que plusieurs personnes partagent un même ordinateur et qu'une même personne se serve de plusieurs ordinateurs. Il arrivera donc que vous ayez besoin de demander à vos utilisateurs de s'identifier à nouveau. Vous devrez en plus leur demander de prouver leur identité.

Le fait de demander à un utilisateur de prouver son identité s'appelle une authentification. La méthode d'authentification la plus courante sur le Web consiste à demander aux utilisateurs de fournir un nom d'utilisateur et un mot de passe valides. L'authentification est également utilisée pour autoriser ou interdire l'accès à certaines pages ou à certaines ressources, mais elle peut être optionnelle, ou encore utilisée dans d'autres buts, comme la personnalisation d'un site.

Implémenter un contrôle d'accès :

Cette opération n'est généralement pas difficile à implémenter. Le code présenté dans le Listing 1 peut fournir trois sorties possibles. Si le fichier est chargé sans paramètre, il affiche un formulaire HTML demandant un nom d'utilisateur et un mot de passe. Ce type de formulaire est représenté à la figure 1.

Si des paramètres sont fournis, mais qu'ils ne soient pas corrects, le programme affiche un message d'erreur comme sur la figure 2.

Si ces paramètres sont présents et corrects, le programme affiche un contenu secret comme sur la figure 3.

Le code permettant de créer les fonctionnalités illustrées par les figures 1, 2 et 3 est présenté dans les Listings 1 et 2

Listing 1. - Bienvenue_Page_Secrete.php - Un mécanisme d'authentification à base de PHP et de HTML :

Listing 2. - Bienvenue_sur_la_Page_de_CEI.php - Un mécanisme d'authentification à base de PHP et de HTML (Suite) :

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1].

Si vous avez bien examiné le code du Listing 2, nous avons fourni le Nom d'utilisateur (Jean-Pierre) ainsi que le Mot de passe (Domestique), afin que vous puissiez vous rendre compte du bon déroulement du programme.

Les codes des Listings 1 et 2 fournissent un mécanisme d'authentification simple, permettant aux utilisateurs autorisés de voir le contenu d'une page, mais il pose plusieurs problèmes.

En effet, ce script :

Possède un nom d'utilisateur et un mot de passe codés directement dans son code source.

Enregistre le mot de passe en clair dans le code source.

Ne protège qu'une seule page.

Transmet le mot de passe en clair.

Ces problèmes peuvent être résolus de différentes manières.

Enregistrement des mots de passe :

Il vaut mieux éviter d'enregistrer les noms d'utilisateur et les mots de passe dans un script. A l'intérieur d'un script, ces données sont difficiles à modifier. Il est toujours possible d'écrire un script qui se modifie lui-même, mais cela n'est généralement pas une bonne idée. Cela signifie, en effet que vous possédez un script sur votre serveur, qui est exécuté sur votre serveur et accessible en écriture pour tout le monde. L'enregistrement de ces informations dans un autre fichier de votre serveur vous permet d'écrire plus facilement un programme pour ajouter ou pour supprimer des utilisateurs, et de modifier leur mot de passe.

Dans un script ou dans un fichier brut, il existe une limite sur le nombre d'utilisateurs que vous pouvez enregistrer sans affecter sérieusement les performances du script. Si vous avez l'intention d'enregistrer un grand nombre d'éléments dans un fichier pour pouvoir les parcourir ultérieurement, il vaut mieux utiliser une base de données, comme nous l'avons déjà vu. D'une manière générale, si vous possédez une liste de plus de 100 éléments, il vaut mieux les placer dans une base de données que dans un fichier brut.

L'utilisation d'une base de données pour enregistrer les noms d'utilisateur et les mots de passe ne rend pas le script beaucoup plus complexe, et cela vous permet d'authentifier très rapidement plusieurs utilisateurs différents. Cela vous permet aussi d'écrire facilement un script pour ajouter de nouveaux utilisateurs, pour supprimer des utilisateurs également, et pour permettre aux utilisateurs de modifier leur mot de passe.

Le Listing 3 permet de créer vos tableaux de la base de données MySQL.

Listing 3. - Create_Auteur_Authentification.sql - Ces requêtes MySQL permettent de créer la base de données auteur, le tableau auteur, et trois utilisateurs :

Le Listing 4 permet de créer votre formulaire relativement simple pour vos essais, il est intéressant de répéter et de faire des révisions que ce soit sur le plan PHP ou HTML.

Listing 4. - Bienvenue_Page_Secrete_2.php - Tout simplement un formulaire comprenant deux champs, un nom d'utilisateur et un mot de passe :

Le Listing 5 présente un script permettant d'authentifier les visiteurs d'une page, grâce à une base de données.

Listing 5. - Bienvenue_sur_la_Page_de_CEI_2.php - Utilisation de MySQL pour améliorer notre système d'authentification de base :

Et enfin, vous trouverez le Listing 6 de connexion concernant le serveur local "easyPHP". Pour les serveurs à distant, vous devez changer les paramètres de connexion.

Listing 6. - Config_Authentification.php - Utilisation pour la connexion, uniquement pour serveur local :

La base de données que nous utilisons peut être créée, en ouvrant une sessions MySQL sous le nom de l'utilisateur root, et en exécutant le contenu du Listing 3.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Si vous avez bien examiné le code du Listing 5 concernant l'exemple 2, nous avons fourni les Noms d'utilisateur : "Jean-Pierre", "Daniel", "Paul" dans la base de données ainsi que les Mots de passe : "Domestique", "User", "123456", (123456 pour Paul) afin que vous puissiez vous rendre compte du bon déroulement du programme.

Cryptage des mots de passe :

Que nous enregistrions nos données dans une base de données ou dans un fichier, il vaut mieux éviter d'enregistrer les mots de passe dans un format non crypté. Un algorithme de hachage unidirectionnel permet d'améliorer la sécurité d'une manière très simple.

La fonction PHP crypt() est une fonction de hachage cryptographique unidirectionnelle. Voici le prototype de cette fonction :

    string crypt (string str [, string salt] )

A partir de la chaîne str, cette fonction renvoie une chaîne pseudo-aléatoire. Par exemple, à partir de la chaîne "pass" et de la clé de cryptage "xx", crypt() renvoie "xxkT1mYjlikoI". Cette chaîne ne peut pas être décryptée et retransformée en "pass", même par son créateur. C'est pourquoi l'intérêt de cette fonction ne semble pas évident. La caractéristique la plus intéressante de crypt() est que sa sortie est déterministe. Pour une chaîne et une clé de cryptage données, la fonction crypt() renvoie toujours le même résultat.

Au lieu de choisir un code PHP comme celui-ci :

    if ($username == "user" && $password == "pass" )

    {

      // Ok, les mots de passe correspondent.

    }

Il vaut mieux choisir :

    if ($username == "user" && crypt($password, "xx") == "xxkT1mYjlikoI" )

    {

      // Ok, les mots de passe correspondent.

    }

Nous n'avons pas besoin de connaître la chaîne qui s'est transformée en "xxkT1mYjlikoI" à l'aide de crypt(). Il suffit de comparer les deux mots de passe cryptés.

Comme nous l'avons déjà vu, il vaut mieux éviter de coder directement dans un script les noms des utilisateurs et les mots de passe associés. Il vaut mieux les enregistrer dans un fichier séparé ou dans une base de données.

Si nous utilisons une base de données MySQL pour enregistrer nos données d'authentification, nous pouvons nous servir de la fonction PHP crypt() ou de la fonction MySQL PASSWORD(). Ces deux fonctions ne fournissent pas le même résultat, mais elles ont le même but. En effet, crypt() et PASSWORD() prennent en argument une chaîne de caractères, et y appliquent un algorithme de hachage non réversible.

Pour utiliser PASSWORD(), nous pouvons écrire la requête SQL du Listing 5 comme ceci :

    $query = "SELECT COUNT(*) FROM auteur WHERE Nom = '$Nom' AND Pass = password('$Mot_de_Passe')" ;

Cette requête compte le nombre de lignes du tableau "auteur" dont la valeur dans la colonne "Nom" correspond au contenu de $Nom, et dont la valeur dans la colonne "pass" est identique à la sortie de PASSWORD() appliquée sur le contenu de $Mot_de_Passe. En supposant que nous obligeons nos utilisateurs à choisir des noms d'utilisateur uniques, le résultat de cette requête est soit 0, soit 1.

Nous terminons ainsi cette onzième leçon et nous verrons dans la prochaine, L'interaction avec le sytème de fichiers et le serveur.


Lecture, Écriture, Création et Suppression de Dossiers

Interaction avec le système de fichiers et le serveur (2ème partie) :

Utilisation de fonctions de manipulation de dossiers :

Lorsque des utilisateurs ont téléchargés des fichiers sur un serveur, il peut leur être très utile de visualiser les données qui ont été téléchargées, et de manipuler le contenu des fichiers qu'ils ont téléchargés.

Le langage PHP offre tout un jeu de fonctions de manipulation des dossiers et du système de fichiers très utilse pour implémenter une telle fonctionnalité.

Lecture du contenu de dossiers :

Nous allons commencer par implémenter un script permettant de parcourir des dossiers pour explorer le contenu téléchargé. Avec PHP, la navigation dans des dossiers est très simple à mettre en œuvre. Le Listing 3 contient un script simple qui peut être utilisé à cette fin.

Listing 3. - Uploader_Lecture.php - Contenu d'un dossier contenant des fichiers téléchargés :

Ce script met en œuvre les fonctions opendir(), readdir() et closedir().

La fonction opendir() s'utilise pour ouvrir un dossier en lecture. Son usage est comparable à celui de la fonction fopen(), si ce n'est que celle-ci s'emploie pour ouvrir des fichiers. Au lieu de passer un nom de fichier à la fonction opendir(), il suffit de lui passer un nom de dossier :

    $dir = opendir($Repertoire_Actuel) ;

opendir() renvoie une poignée sur le dossier qui lui a été passé comme argument, de la même manière que fopen() renvoie une poignée sur le fichier traité.

Une fois qu'un dossier est ouvert, vous pouvez y lire un nom de fichier, en invoquant la fonction readdir($dir), comme dans l'exemple du Listing 3. Cette fonction renvoie la valeur false lorsqu'il n'a pas (ou plus) de fichier à lire (notez qu'elle renvoie également false en présence d'un fichier dénommé "0", ce qui peut bien sûr être testé).

Les fichiers n'étant pas classés dans un ordre particulier, vous devez les lister dans un tableau et les trier pour obtenir une liste triée.

Lorsque la lecture d'un dossier est terminée, la fonction closedir($dir) doit être invoquée pour mettre un terme à l'opération de lecture. Là encore, cette fonction est comparable à son équivalent pour la fermeture d'un fichier : fclose().

Un exemple de résultat obtenu à l'exécution du script du Listing 3 est montré à la figure 3.

Si vous implémentez une navigation dans les dossiers avec un tel mécanisme, il serait peut-être judicieux de restreindre les dossiers "navigables", de sorte qu'un utilisateur ne puisse parcourir le contenu des dossiers situés dans des zones qui ne lui sont pas normalement accessibles.

rewinddir($dir) est une fonction apparentée aux fonctions précédentes, et qui se révèle parfois bien utile. Elle replace le pointeur de dossier tout au début du dossier exploré.

La classe dir fournie par PHP constitue une autre possibilité. Elle est dotée des propriétés handle et path, et des méthodes read(), close() et rewind(), qui offrent une fonctionnalité identique à celle des fonctions de manipulation des dossiers décrites précédemment.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 2].

Obtention d'informations relatives au dossier courant :

En spécifiant un chemin d'accès à un fichier spécifique, nous pouvons obtenir des informations additionnelles.

Les fonctions dirname($Repertoire_Actuel) et basename($Repertoire_Actuel) renvoient respectivement la partie du chemin d'accès représentant le nom du dossier contenant le fichier, et la partie du chemin d'accès représentant le nom du fichier. Ces fonctions peuvent être mises en œuvre dans un dispositif de navigation dans les dossiers, particulièrement lorsqu'une structure de dossiers complexe et élaborée pour le stockage du contenu, avec des noms de dossier et des noms de fichier significatifs.

Au script de navigation dans les dossiers, nous pourrions également ajouter un mécanisme de notification de l'espace restant disponible pour le stockage des fichiers téléchargés, en utilisant la fonction disk_free_space("/"). Lorsqu'un chemin d'accès à un dossier est passé comme argument à cette fonction, celle-ci renvoie le nombre d'octets libres sur le disque dur (Windows) ou le système de fichiers dans lequel se trouve le dossier (Unix).

Création et suppression de dossiers :

PHP nous donne la possibilité non seulement de lire passivement des informations relatives aux dossiers, mais aussi de créer et de supprimer des dossiers, respectivement au moyen des fonctions mkdir() et rmdir(). Il n'est toutefois possible de créer ou de supprimer que les seuls dossiers dont les chemins d'accès sont accessibles par l'utilisateur sous lequel est exécuté le script.

La mise en œuvre de la fonction mkdir() est un peu délicate. Cette fonction prend deux paramètres : le chemin d'accès au dossier à créer (y compris le nom du nouveau dossier), et les permissions dont doit bénéficier ce dossier. Voici un exemple d'utilisation de cette fonction :

    mkdir("/Repertoire/Temporaire", 0777) ;

Toutefois, les permissions ainsi spécifiées ne seront pas nécessairement accordées. La permission accordée sera déterminée en appliquant la variable courante $Permission_Umask à la permission spécifiée. Par exemple, si umask() contient la valeur 022, les permissions accordées seront 0755.

Vous pouvez réinitialiser le umask() avant de créer un dossier, de sorte à contrer cet effet, avec le code suivant :

    $Permission_Umask = umask(0) ;

    mkdir("Dossier", 0777) ;

    umask ($Permission_Umask) ;

Ce code met en œuvre la fonction umask(), qui permet de vérifier et de modifier la valeur courante de umask.umask() donne à umask() la valeur qui lui est passée comme argument, et renvoie l'ancienne valeur de umask(). Si umask() est invoquée sans spécifier de paramètres, elle renvoie uniquement la valeur courante de umask().

La fonction rmdir() supprime le dossier qui lui est passé comme paramètre. En voici deux exemples d'utilisation :

    rmdir("/Repertoire/Temporaire") ;

et

    rmdir("c:\\Repertoire\\Temporaire") ;

Pour supprimer un dossier au moyen de la fonction rmdir(), il est impératif que le dossier soit vide.

Nous vous communiquons le code HTML relativement simple du Listing 4 concernant le formulaire de création de(s) répertoire(s), afin d'en faciliter vos essais.

Listing 4. - Upload_Creer_Repertoire.html - Contenu d'un dossier permettant de créer le(s) répertoire(s) :

Nous vous communiquons également le code PHP du Listing 5 pour l'exécution du script concernant la création de répertoire.

Listing 5. - Upload_Creer_Repertoire.php - Contenu d'un dossier permettant de créer le(s) répertoire(s) à l'exécution du script :

N'oubliez pas de créer le répertoire intitulé Upload_Repertoire, en respectant la casse. Sinon, le script ne peut fonctionner.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Pour supprimer le répertoire que vous aviez créé, il suffit de remplacer la fonction if(@mkdir($Dossier, 0777)) du Listing 5, en remplaçant la fonction ci-après par if(@rmdir($Dossier)) (mkdir() ---> par rmdir()).

Interaction avec le système de fichiers :

En PHP, nous pouvons visualiser et obtenir des informations sur des dossiers, mais nous pouvons également interagir avec et obtenir des informations sur des fichiers stockés sur le serveur Web. Nous avons vu précédemment comment écrire et lire dans des fichiers. PHP offre nombre d'autres fonctions pour la manipulation des fichiers.

Obtention d'informations sur les fichiers :

La part du script du Listing 3 qui lit des fichiers peut être modifiée de la manière suivante :

    while($fichier = $dir->read())

    {

    echo "<b> <a href = \"Upload_Lecture_Fichier.php?file=" . $fichier . "\">" . $fichier . "</a></b> <BR/>" ;

    }

Mais vous risquerez d'obtenir une erreur d'exécution ci-après ; Fatal error : Call to a member function read() on a non-object in C, ce qui signifie en français : Appel à une fonction membre read() sur un non-objet dans C.

Afin d'éviter cette erreur, nous pouvons ensuite créer un script dénommé Upload_Lecture_Fichier.php, pour obtenir plus d'informations sur un fichier. Ce script est donné aux Listings 6 et 7 concernant HTML et PHP.

Listing 6. - Upload_Lecture_Fichier.html - Mise en œuvre d'un formulaire HTML renseignant sur l'état d'un fichier :

Listing 7. - Upload_Lecture_Fichier.php - Mise en œuvre de fonctions renseignant sur l'état d'un fichier :

La figure 4 donne un exemple d'exécution du Listing 7.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 4].

Examinons en détail la tâche accomplie par chacune des fonctions utilisées au Listing 7.

Comme nous l'avons déjà mentionné, la fonction basename() fournit le nom du fichier sans mention du dossier (la fonction dirname() fournirait quant à elle le nom du dossier sans le nom du fichier).

Les fonctions fileatime() et filemtime() renvoient la date et l'heure ("l'horodatage") respectivement du dernier accès au fichier, et de la dernière modification apportée au fichier. L'horodatage ainsi renvoyé est reformaté dans le Listing 7 au moyen de la fonction date(), de sorte à en faciliter la lecture. Avec certains systèmes d'exploitation (comme dans l'exemple considéré ici), ces fonctions renvoient la même valeur, en fonction de l'information stockée par le système.

Les fonctions fileowner() et filegroup() renvoient l'ID utilisateur (uid pour user ID) et l'ID de groupe (gid pour group ID) du fichier. Ces ID peuvent être convertis en noms via respectivement les fonctions posix_getpwuid() et posi_getgrgid(), de sorte à en faciliter la lecture. Ces fonctions prennent respectivement le uid et le gid comme paramètre, et renvoie un tableau associatif contenant des informations sur l'utilisateur ou le groupe, y compris le nom de l'utilisateur ou du groupe (qui n'est pas utilisé dans le script du Listing 7).

La fonction fileperms() renvoie les permissions sur le fichier. Dans le Listing 7, les permissions renvoyées sont reformatées en un nombre octal au moyen de la fonction decoct(), de sorte à leur donner un format plus familier aux utilisateurs Unix.

La fonction filesize() renvoie la taille du fichier en octets.

Le second jeu de fonctions mises en œuvre (is_dir(), is_executable(), is_file(), is_link(), is_readable(), et is_writable()) est utilisé pour tester les différents attributs du fichier. Toutes ces fonctions renvoient true ou false.

La fonction stat() aurait également pu être employée pour obtenir une grande part de ces informations. Lorsqu'un fichier lui est passé comme argument, cette fonction renvoie un tableau rassemblant des informations semblables à celles renvoyées par les fonctions citées plus haut. La fonction lstat() est identique à la fonction stat(), si ce n'est qu'elle s'emploie avec des liens symboliques.

Toutes les fonctions d'information sur l'état d'un fichier se révèlent coûteuses en termes de temps d'exécution. C'est pourquoi les données qu'elles renvoient sont placées dans la mémoire cache. Pour obtenir des informations sur l'état d'un fichier donné, avant et après modification de ce fichier, invoquez la fonction ci-après :

    clearstatcache() ;

pour effacer les résultats précédents. Par exemple, pour utiliser le script du Listing 7 avant et après avoir apporté des changements aux données du fichier, il faudrait tout d'abord s'assurer que les données renvoyées sont à jour en invoquant cette fonction.

Interaction avec l'environnement - getenv() et putenv() :

Nous terminerons cette leçon, en examinant comment utiliser des variables d'environnement à partir du code PHP. Deux fonctions sont disponibles à cet effet : getenv(), qui permet de retrouver des variables d'environnement, et putenv(), qui s'emploie pour ajuster des variables d'environnement.

Notez que l'environnement considéré ici est l'environnement dans lequel PHP est exécuté sur le serveur.

Vous pouvez obtenir la liste de toutes les variables d'environnement PHP en exécutant la fonction phpinfo(). Certaines variables sont plus utiles que d'autres, par exemple :

    $ip = getenv('HTTP_REFERER') ;

    echo $ip ;

renvoie l'URL de la page à partir de laquelle l'utilisateur a accédé à la page courante.

Vous pouvez aussi ajuster des variables d'environnement, selon vos besoins, par exemple :

    $home = "/home/electronique" ;

    putenv ("HOME = $home") ;

Nous terminons ainsi cette douzième leçon et nous verrons dans la prochaine, la Génération d'images via PHP sur certains programmes.


Représentation Graphique de Données Numériques

Génération d'images via PHP (2ème partie) :

Utilisation de Représentation graphique de données numériques :

Dans la dernière application étudiée, nous avons manipulé des images et du texte existant. Nous allons à présent examiner un exemple de dessin dynamique via PHP.

Dans l'exemple considéré dans cette deuxième partie de cette leçon, un sondage est implémenté sur un site Web pour établir les intentions de vote des visiteurs du site, en prévision d'une élection fictive. Les résultats du sondage en ligne sont stockés dans une base de données MySQL, puis exploités sour la forme d'un graphique à barres, en utilisant des fonctions PHP de manipulation d'image.

Le tracé de graphes constitue l'autre grand domaine d'utilisation des fonctions PHP de création et de manipulation d'image. Vous pouvez tracer des graphes à partir de tout jeu de données, comme des données relatives aux ventes, ou à la fréquentation d'un site. L'exemple considéré ici nécessite la création d'une base de données dénommée jean_pierre. Cette base de données contient une table appelée jean_pierre_resultats, qui stocke dans la colonne Candidats le nom des canditats à l'élection, et dans la colonne Nombre_de_Votes, le nombre de votes reçu par chaque candidat. Un utilisateur doit être défini pour cette base de données, sous le nom de jean_pierre, et avec le mot de passe jean_pierre. Ce travail préliminaire de création de la base de données peut s'effectuer en quelques minutes, en exécutant le script SQL, donné au Listing 1. Vous pouvez exécuter ce script en pipe via le moniteur SQL.

Bien entendu, vous pouvez également ouvrir une session avec les identifiants de tout utilisateur bénéficiant des privilèges MySQL appropriés, qui se trouve en votre possession.

Listing 1. - Jean_Pierre_Setup_Votes.sql - Création et configuration de la base de données Jean_Pierre :

Concernant les serveurs à distant, vous devez supprimer use jean_pierre ainsi que to jean_pierre@localhost et identified by 'jean_pierre' ; dans le Listing 1. Sinon, pose problème.

(A cette occasion, nous mettons un fichier à télécharger dans l'intitulé Police "TrueType Arial.ttf", en cliquant ici, et à mettre ce même fichier dans le même répertoire de votre script que l'on verra plus bas de cette leçon).

Ainsi configurée, cette base de données contient six candidats. Le fichier Vote_Resultats.html fournit l'interface pour ce sondage en ligne. Son contenu est montré au Listing 2.

Listing 2. - Vote_Resultats.html - Les Internautes peuvent exprimer leur intention de vote dans ce formulaire :

Le résultat du chargement de la page Vote_Resultats.html est montré à la figure 1.

Le principe de cette application est le suivant : lorsqu'un utilisateur clique sur le bouton Submit, son vote doit tout d'abord être ajouté à la base de données Jean_Pierre (en local), puis à la table jean_pierre_resultats (serveur à distant). Ensuite, les résultats courants du sondage, y compris l'intention de vote qui vient d'être exprimée, doivent être affichés sous la forme de graphe à barres.

Le résultat affiché après la saisie d'une intention de vote est montré à la figure 2.

Pour visualiser l'aperçu, en cliquant ici. [Exemple 3].

Le script générant l'image montrée à la figure 2 est assez long. Pour en simplifier l'étude, nous le décomposerons en quatre parties, que nous examinerons séparément. Ensuite, vous trouverez le script en totalité, en bas de page de cette leçon.

L'essentiel de ce script vous est déjà familier. Nous avons examiné jusqu'ici nombre d'exemples MySQL qui sont analogues à cette application. Par ailleurs, vous avez précédemment appris à peindre un canevas d'arrière-plan avec une couleur unie, et à dessiner des intitulés textuels, par exemple, sur des boutons.

Tout d'abord, nous mettons le script de connexion que vous connaissiez déjà dans le Linting 3, puisque ce script étant séparé des autres donc, ce fichier est intitulé Config_Connect_Vote.php : il suffit de rappeler ce fichier par les fonctions require() ou include().

Listing 3. - Config_Connect_Vote.php - Permettant de vous connecter à votre base de données de chez Jean_Pierre, en local :

Les parties de ce script qui sont résolument nouvelles dans le contexte de cette leçon sont celles qui concernent le dessin de traits et de rectangles. Nous nous concentrerons donc particulièrement sur ces sections. La première partie (des quatre parties que compte ce script) est donnée au Listing 4. 1.

Listing 4. 1. - Sondages.php - La partie 1 actualise la base de données et récupère les nouveaux résultats :

Cette première partie établit la connexion avec la base de données MySQL, actualise les intentions de vote, en prenant en compte les données entrées par l'utilisateur, et récupère les résultats courants du sondage. Une fois les informations ainsi récupérées, les calculs nécessaires à la représentation graphique de ces informations peuvent être effectués. La partie 2 de cette application est donnée au Listing 4. 2.

Listing 4. 2. - Sondages.php - La partie 2 définit toutes les variables nécessaires au tracé du graphe :

La deuxième partie de l'application consiste, en la définition des variables nécessaires au tracé du graphe.

Le choix des valeurs pour ces variables peut se révéler assez laborieux. Toutefois, vous faciliterez le processus de dessin, en vous attachant à définir précisément l'apparence que vous voulez finalement obtenir. Les valeurs spécifiées ici ont ainsi été obtenues, en esquissant sur une feuille de papier le graphe désiré, et en estimant les proportions requises.

La variable $Largeur stocke la largeur totale du canevas utilisé. Les marges gauche et droite doivent également être définies (avec respectivement $left_margin et $right_margin), ainsi que l'épaisseur et l'espacement des barres ($bar_height et $bar_spacing), la police, les tailles de police et la position des étiquettes textuelles ($font, $title_size, $main_size, $small_size, et $text_indent).

A partir de ces valeurs de base, plusieurs calculs peuvent être effectués. Une ligne de base doit être tracée, qui servira de ligne de départ à chacune des barres. La position de cette ligne de base est définie à partir de la marge gauche, en prenant en compte l'espace nécessaire à l'affichage des étiquettes textuelles de l'axe des X, et la longueur maximale autorisée des barres.

Deux autres valeurs importantes sont également déterminées dans cette deuxième partie : tout d'abord, la distance sur le graphe qui représente une unité :

    $bar_unit = (Largeur - ($x + $right_margin)) / 100 ; // Un "point" sur le graphe.

La largeur d'un point est obtenue, en divisant la longueur maximale d'une barre par 100 (puisque ce graphe va représenter des valeurs en pourcentage).

La deuxième valeur importante est la hauteur totale requise pour le canevas :

    $height = $Nombre_Candidats * ($bar_height + $bar_spacing) + 70 ;

Cette valeur est obtenue, en multipliant l'épaisseur d'une barre par le nombre de barres, et en ajoutant une longueur supplémentaire pour l'affichage du titre.

La Partie 3 de ce script est montrée au Listing 4. 3.

Listing 4. 3. - Sondages.php - La partie 3 définit le graphe, de sorte qu'il soit prêt à recevoir des données :

Cette troisième partie de l'application définit l'image de base, alloue les couleurs, puis commence le tracé du graphe.

L'arrière-plan du graphe est peint au moyen de la fonction suivante :

    ImageFilledRectangle($image, 0, 0, $Largeur, $height, $bg_color) ;

La fonction ImageFilledRectangle(), comme son nom l'indique, dessine un rectangle rempli d'une couleur unie. Son premier paramètre est, comme d'habitude, l'identificateur de l'image. La fonction prend ensuite comme argument les coordonnées X et Y du point initial et du point final du tracé du rectange. Ceux-ci correspondent respectivement au coin supérieur gauche et au coin inférieur droit du rectangle. Dans ce cas précis, l'intégralité du canevas est rempli avec la couleur d'arrière-plan, spécifiée dans le dernier paramètre (le blanc). L'appel suivant :

    ImageRectangle($image, 0, 0, $Largeur - 1, $height - 1, $line_color) ;

provoque ensuite le tracé d'une bordure noire encadrant le canevas. La fonction ImageRectangle() trace le contour d'un rectangle au lieu de dessiner un rectange plein. Ses paramètres sont identiques à ceux de la fonction ImageFilledRectangle(). Notez que le rectangle est ici dessiné jusque $Largeur - 1 et $height - 1 (c'est-à-dire de 0,0 jusqu'à ces valeurs). Si le rectangle avait été dessiné jusque $Largeur et $height, il serait "sortie" de la zone du canevas.

Pour écrire le titre du graphe, la même logique et les mêmes fonctions que celles de l'exemple précédent ont été utilisées.

Et pour finir, la ligne de base des barres est tracée, au moyen de la ligne de code suivante :

    ImageLine($image, $x, $y - 10, $x, $height - 20, $line_color) ;

La fonction ImageLine() dessine un trait sur l'image spécifiée à gauche ($image), du point défini par un jeu de coordonnées ($x, $y - 10), jusqu'à un autre point lui aussi défini par ses coordonnées ($x, $height - 20), dans la couleur spécifiée par $line_color.

Dans ce cas, la ligne de base est tracée à gauche du canevas, en partant d'un point situé légèrement au-dessus de la position de départ de la première barre, jusqu'à un point situé légèrement en-dessous du bas du canevas.

A ce stade, les données peuvent être représentées dans le graphe. La partie 4 du script est donnée au Listing 4. 4.

Listing 4. 4. - Sondages.php - La partie 4 dessine les données sur le graphe et achève le script :

La partie 4 traite un à un les candidats stockés dans la base de données, détermine le pourcentage des intentions de vote, et trace les barres et les étiquettes textuelles pour chaque candidat.

Là aussi, les étiquettes textuelles sont tracées au moyen de la fonction ImageTTFText(). Les barres sont dessinées sous la forme de rectangles pleins, au moyen de la fonction ImageFilledRectangle(), comme suit :

    ImageFilledRectangle($image, $x, $y - 2, $bar_length, $y + $bar_height, $bar_color) ;

Les bords représentant la limite des 100 % sont tracés au moyen de la fonction ImageRectangle() comme suit :

    ImageRectangle($image, $bar_length + 1, $y - 2, ($x + (100 * $bar_unit)), $y + $bar_height, $line_color) ;

Une fois toutes les barres tracées, la fonction ImagePNG() est utilisée pour afficher l'image dans le navigateur. Un nettoyage final est ensuite effectué au moyen de la fonction ImageDestroy().

A noter : nous sauvegardons l'image du sondage sur le disque dur pour la restaurer par la suite au moyen du langage HTML pour des raisons techniques, comme suit : (voir le Listing 4. 1.)

    <CENTER> <img src = 'Rectangle.png' alt = 'Rectangle.png' border = '0' width = '580' height = '380'> </CENTER>

Cette image dynamique du canevas ci-dessus se mettra à jour automatiquement d'où le nom sus évoqué.

Le script de cet exemple, s'il est plutôt long, présente l'avantage d'être facilement adaptable à des besoins spécifiques. Ce script ne comprend toutefois pas de mécanisme ainti-fraude. Les utilisateurs découvriraient rapidement qu'ils peuvent voter plusieurs fois, faussant ainsi la légitimité du sondage.

L'approche décrite dans cet exemple peut également être suivie pour dessiner des graphes linéaires, voire des diagrammes circulaires, à condition toutefois d'être versé dans l'art des mathématiques.

Listing 4. 5. - Sondages.php - La partie 5 - Le script complet du sondage :

N'oubliez pas d'insérer le script de connexion du Listing 3 dans l'intitulé Config_Connect_Vote.php se trouvant à part, concernant le script du Listing 4. 5. (voir la fonction require().

Autres fonctions de création et de manipulation d'image :

Outre les fonctions d'image utilisées dans cette leçon, PHP offre des fonctions qui permettent de tracer des lignes courbes (ImageArc()) et des polygones (ImagePolygon()), ainsi que diverses variantes des fonctions mises en œuvre jusqu'ici. Attachez-vous à toujours planifier vos tracés avant de vous plonger dans cette leçon pour trouver les fonctions qui vous permettrons d'atteindre l'objectif recherché.

Vous trouverez également en ligne, une abondante documentation écrite sur ce sujet. Si vous rencontrez des difficultés lors de la mise en œuvre d'une fonction de création ou de manipulation d'image, vous gagnerez sans doute du temps à consulter la documentation d'origine de la bibliothèque GD, car les fonctions PHP sont des enveloppes pour cette bibliothèque. Cette documentation est disponible à l'URL ci-après : en cliquant ici.

Il existe également sur le Web d'excellents didacticiels sur des types particuliers d'applications de tracé de graphes, notamment sur les sites Web suivants :

http://www.zend.com, en cliquant ici.

http://devshed.com, en cliquant ici.

L'application de tracé de graphe à barres décrite dans cette leçon, s'inspire du script de tracé dynamique de graphe à barres écrit par Steve Maranda et disponible sur le site de Devshed, en anglais.

Nous terminons ainsi cette treizième leçon et nous verrons dans la prochaine, l'Authentification des Utilisateurs et Personnalisation du site.


Sommaire - Implémenter un Caddie

Sommaire - Implémenter un Caddie (1ère partie) :

Dans cette leçon, nous verrons comment implémenter les fonctionnalités de base d'un caddie. Nous ajouterons ce caddie à la base de données de chez Jean-Pierre, que nous avons implémentée dans une de nos leçons. Nous explorerons également une autre solution : la configuration et l'utilisation d'un caddie PHP qui existe déjà en Open Source, et que nous nous sommes inspiré de ce dernier malgré certaines erreurs sur le Net concernant la programmation.

Si vous ne connaissez pas le principe d'un caddie électronique (que l'on appelle également parfois une carte d'achat, ou un panier d'achat), il s'agit d'un mécanisme permettant d'effectuer des achats en ligne. Au fur et à mesure que vous parcourez le catalogue en ligne d'un site, vous pouvez ajouter des articles dans votre caddie. Lorsque vous avez fini vos achats, il suffit de sortir du magasin en ligne, et de régler les articles qui se trouvent dans votre caddie.

Pour implémenter notre caddie, nous avons besoin des fonctionnalités suivantes :

Une base de données des produits que nous voulons vendre en ligne ;

Un catalogue en ligne de nos produits, listés par catégorie ;

Un caddie pour conserver une trace des articles que l'utilisateur souhaite acheter ;

Un script de sortie qui s'occupe du paiement et des détails de la transaction ;

Une interface d'administration.

Le problème :

Vous vous souvenez probablement de la base de données de chez Jean-Pierre que nous avons développée dans une de nos leçons à partir de cette adresse URL : en cliquant ici. Dans ce projet, nous allons implémenter et mettre en œuvre le magasin en ligne de chez Jean-Pierre. Voici le cahier des charges de ce système :

Il nous faut un moyen de connecter la base de données au navigateur de l'utilisateur. Les utilisateurs doivent être capables de parcourir les articles par catégorie.

Les utilisateurs doivent également être capables de sélectionner des articles dans le catalogue, pour pouvoir les acheter plus tard. Nous devons conserver une trace des articles sélectionnés.

Lorsque les utilisateurs ont terminé leurs achats, nous devons calculer le montant total de leur commande, enregistrer les détails de la commande (comme l'adresse de la livraison) et traiter le paiement.

Il nous faut également construire une interface d'administration pour le site de chez Jean-Pierre, afin que l'administrateur puisse ajouter et modifier certaines informations de ces articles concernant les ouvrages, ainsi que des catégories de livres que les administrateurs peuvent ajouter ou supprimer par la suite ...

Implémenter un catalogue en ligne :

Essayons maintenant de trouver une solution pour chaque partie à implémenter.

Nous possédons déjà une base de données pour le catalogue de chez Jean-Pierre. Cependant, nous devons y apporter quelques modifications pour cette application. Il faudra notamment ajouter des catégories de livres, comme nous venons de le voir.

Il faudra aussi ajouter certaines informations dans notre base de données, pour les adresses de paiement, les détails des transactions, etc. ...

Nous savons déjà comment implémenter une interface vers une base de données MySQL à l'aide de PHP, donc cette partie devrait être assez simple.

Conserver une trace des achats effectués par l'utilisateur :

Nous avons pour cela deux techniques à notre disposition. La première consiste à ajouter les sélections effectuées dans notre base de données, et l'autre passe par l'utilisation d'une variable de session.

L'utilisation d'une variable de session est plus simple à écrire, puisqu'elle ne monopolise pas en permanence la base de données. Cela nous évite aussi de saturer la base de données avec des informations inutiles, si les utilisateurs effectuent des sélections et s'ils quittent le site avant de passer une commande.

Nous avons besoins par conséquent d'implémenter une variable de session, ou un ensemble de variables pour enregistrer les sélections d'un utilisateur. Lorsqu'un utilisateur a fini de sélectionner ses acticles et qu'il passe à la caisse, nous ajoutons ces informations dans notre base de données pour conserver une trace de la transaction.

Nous pouvons également nous servir de ces données pour résumer l'état actuel du crédit dans un coin de la page, de sorte que l'utilisateur sache en permanence ce qu'il a déjà sélectionné.

Paiement :

Dans ce projet, les utilisateurs se contentent de sélectionner des articles et de saisir les informations nécessaires pour la commande. Nous ne traiterons pas réellement les paiements. Il existe un grand nombre de systèmes de paiement en ligne, et leurs implémentations sont toutes différentes. Nous nous contenterons donc d'écrire une fonction de base, qui pourra être remplacée par une interface vers le système de votre choix. Toutefois, nous vous aiderons pour le paiement via PayPal concernant les paramètres que l'on verra par la suite de cette leçon mais, vous devrez ouvrir un compte de votre choix, on ne peut choisir pour vous !

Les systèmes de paiement sont généralement vendus spécifiquement pour chaque pays. Les interfaces de traitement en temps réel fonctionnent la plupart du temps de la même manière. Il faut notamment se procurer un compte commercial auprès d'une banque pour pouvoir accepter les cartes de crédit. Le fournisseur de votre système de paiement vous spécifiera les paramètres que vous devrez passer à son système.

Le système de paiement transmet vos informations à une banque, et renvoie un code de résultat ou d'identification qui indique le succès de la transaction ou une erreur. En échange de cette transmission d'informations, votre passerelle de paiement vous facturera une somme basée sur une charge mensuelle ou annuelle selon les fournisseurs, ainsi qu'une taxe basée sur le nombre ou la valeur de vos transactions. Certains fournisseurs de systèmes de paiement vous font même payer en cas de transaction annulée.

Le système de paiement choisi aura besoin d'informations sur le client (comme son numéro de carte de crédit ou bancaire), ainsi que les informations permettant de vous identifier pour connaître le compte commercial à créditer, et du montant total de la transaction.

Le montant total de la commande se trouve déjà dans la variable de session du caddie de l'utilisateur. Nous enregistrons les détails de la commande dans la base de données, et nous pouvons donc nous débarrasser de la variable de session à partir de ce moment-là. Car, il ne faut jamais enregistrer les numéros de carte bancaire dans une base de données pour éviter, en cas de fraude ou d'anomalie de dysfonctionnement d'une base de données, cela implique une responsabilté pour toute personne administrateur système, en cas de fraude donc à ses risques et périls.

Interface d'administration :

En plus de tout cela, nous devons implémenter une interface d'administration nous permettant d'ajouter, de supprimer, et de modifier les livres et les catégories de livres dans la base de données.

Par exemple, il peut être nécessaire de modifier le prix d'un article, notamment en période de promotion. Cela signifie que lorsque nous enregistrons la commande d'un client, il faut enregistrer le prix de l'article commandé. La gestion de ce site deviendrait rapidement très complexe si nous nous contentions d'enregistrer les articles commandés par chaque client, et le prix de chaque article, indépendamment. Cela signifie également que si le client souhaite de nous renvoyer un article ou l'échanger, nous pouvons lui fournir un bon de commande de la somme correspondante.

Dans ce projet, nous n'implémenterons aucune interface de suivi de commande. Nous vous laissons le plaisir d'en ajouter une sur ce système de base, en fonction de vos besoins.

Présentation de la solution :

Nous allons maintenant assembler tous les composants nécessaires de notre projet.

Notre système peut être considéré, en fonction de deux points de vue différents : le point de vue de l'utilisateur et le point de vue de l'administrateur. Après avoir étudié les fonctionnalités nécessaires, nous avons pu mettre en place deux architectures différentes, une pour chaque point de vue. Elles sont présentées aux figures 1 et 2, respectivement.

Dans la figure 1, nous présentons les principales relations entre les scripts de la partie utilisateur de ce site. Les clients arrivent d'abord sur la page principale, qui présente la liste de toutes les catégories de livres vendus sur le site. A partir de là, les clients peuvent aller sur la page dédiée à chaque cétégorie de livres, et ensuite sur la page de chaque livre appartenant à cette catégorie.

Il faut fournir à l'utilisateur un lien permettant d'ajouter un livre dans son caddie. A partir du caddie, le client doit pouvoir sortir du magasin et passer sa commande.

La figure 2 représente l'interface de l'administrateur, qui contient plus de scripts, mais moins de code. Ces scripts permettent à un administrateur d'ouvrir une session et de travailler sur les livres et les catégories.

Le moyen le plus simple pour implémenter les manipulations sur les livres et sur les catégories de livres consiste à afficher une version légèrement différente de l'interface de l'utilisateur. L'administrateur sera toujours capable de parcourir les catégories et les livres, mais au lieu d'accéder au caddie, l'administrateur pourra manipuler les livres et les catégories. En modifiant les scripts pour qu'ils puissent s'adapter à la fois aux administrateurs et à ses clients, nous pouvons économiser beaucoup de temps et beaucoup d'efforts.

Voici les trois modules de code principaux de cette application :

Le catalogue ;

Le caddie et le traitement des commandes (nous les avons placés dans le même module parce qu'ils ont beaucoup de points communs) ;

L'administration.

Comme dans le projet précédent, nous allons également implémenter et utiliser plusieurs bibliothèques de fonctions. Pour ce projet, nous utiliserons une API de fonctions analogue à celle du projet précédent. Nous tenterons de confiner la partie de notre code qui génère une sortie HTML dans une seule bibliothèque, pour nous conformer au principe de séparation de la logique et du contenu, et surtout pour que notre code soit plus simple à lire et à maintenir.

Nous devons également apporter quelques modifications mineures dans la base de données de chez Jean-Pierre. Nous avons renommé cette base de données en book_sc_livre (pour Shopping Cart, c'est-à-dire carte d'achat, ou caddie), afin de la différencier de celle que nous avons implémentée dans une de nos leçons, à savoir "Authentifier les Utilisateurs et personnaliser le site" à cette URL, en cliquant ici.

Tous les fichiers en langage PHP, que nous verrons par la suite de ce projet se trouvent dans le tableau 1 contient donc, un résumé de ces fichiers, en respectant la casse.

Cependant, nous avons regroupé tous les fichiers au format ZIP, (il suffit de les décompresser) afin que vous puissiez les télécharger avec ou sans carte bancaire concernant le caddie.

Avec Carte Bancaire, en cliquant ici. [Exemple 1].

Sans Carte Bancaire, en cliquant ici. [Exemple 1 - bis].

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1 - ter].

Tableau 1. - Les fichiers de l'application "Shopping Cart Livre", en respectant la casse.
Nom | Module | Description
index.php | Catalogue | Page d'accueil du site pour les utilisateurs. Affiche la liste des catégories du système.
show_cat.php | Catalogue | Affiche tous les livres d'une catégorie particulière.
show_book.php | Catalogue | Affiche les détails d'un livre particulier.
show_cart.php | Caddie | Affiche le contenu du caddie. Également utilisé pour ajouter des articles dans le caddie.
checkout.php | Caddie | Affiche les détails complets de la commande. Récupère les détails de la transaction.
purchase.php | Caddie | Récupère les détails de paiement de l'utilisateur.
process.php | Caddie | Traite les détails de paiement et ajoute la commande dans la base de données.
login.php | Administration | Permet aux Administrateurs d'ouvrir une session et d'apporter des modifications.
logout.php | Administration | Permet aux Administrateurs de fermer une session.
admin.php | Administration | Menu principal d'administration.
change_password_form.php | Administration | Formulaire permettant aux Administrateurs de modifier leur mot de passe.
change_password.php | Administration | Modifie le mot de passe des Administrateurs.
insert_category_form.php | Administration | Formulaire permettant aux Administrateurs d'ajouter une nouvelle catégorie dans la base de données.
insert_category.php | Administration | Insert une nouvelle catégorie dans la base de données.
insert_book_form.php | Administration | Formulaire permettant aux Administrateurs d'ajouter un nouveau livre dans le système.
insert_book.php | Administration | Insère un nouveau livre dans la base de données.
edit_category_form.php | Administration | Formulaire permettant aux Administrateurs de modifier une catégorie.
edit_category.php | Administration | Met à jour une catégorie dans la base de données.
edit_book_form.php | Administration | Formulaire permettant aux Administrateurs de modifier les détails d'un livre.
edit_book.php | Administration | Met à jour un livre dans la base de données.
delete_category.php | Administration | Supprime une catégorie dans la base de données.
delete_book.php | Administration | Supprime un livre dans la base de données.
book_sc_fns.php | Fonctions | Ensemble de fichiers à inclure pour cette application.
admin_fns.php | Fonctions | Ensemble de fonctions utilisées par les scripts d'administration.
book_fns.php | Fonctions | Ensemble de fonctions permettant d'enregistrer et de lire les données d'un livre.
order_fns.php | Fonctions | Ensemble de fonctions permettant d'enregistrer et de lire les données d'une commande.
output_fns.php | Fonctions | Ensemble de fonctions permettant de sortir du code HTML.
data_valid_fns.php | Fonctions | Ensemble de fonctions permettant de valider les données d'entrée.
db_fns.php | Fonctions | Ensemble de fonctions permettant de se connecter à la base de données book_sc_livre.
config.php | Fonctions | Ensemble de fonctions permettant de se connecter à la base de données.
user_auth_fns.php | Fonctions | Ensemble de fonctions permettant d'authentifier les Administrateurs.
Book_SC.sql | SQL | Requêtes SQL pour initialiser la base de données book_sc_livre.
populate.sql | SQL | Requêtes SQL permettant d'insérer quelques données, en exemple dans la base de données book_sc_livre.
images | Imagerie | Répertoire d'images et schémas de catalogue.

Intéressons-nous maintenant à l'implémentation de chacun de ces modules.

Nous attirâmes votre attention que cette application contient beaucoup de code. Cependant, nous implémenterons essentiellement des fonctionnalités que nous avons déjà vues (en particulier au cours de notre leçon précédente), comme l'enregistrement et la lecture de données dans la base de données, et l'authentification des administrateurs. Nous passerons très rapidement sur ces parties, pour nous concentrer sur les fonctions du caddie.

Pour que le code de ce projet fonctionne tel qu'il est écrit, vous devez activer les guillemets magiques. Dans le cas contraire, vous devez vous servir de addslashes() pour enregistrer des données dans la base de données MySQL, et de stripslashes() pour les récupérer.

Vous pouvez activer les guillemets magiques pour chaque dossier à l'aide d'un fichier .htaccess en spécifiant la directive php_value magic_quotes on (pour PHP 4), ou php3_magic_quotes_gpc on (pour PHP 3), etc. ...

Nous terminons ainsi ce premier chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation de la base de données, l'implémentation du catalogue en ligne, liste des livres d'une catégorie et bien d'autres encore ...


Implémentation de la base de données et Catalogue en ligne

Implémentation d'un Caddie (2ème partie) :

Implémentation de la base de données :

Comme nous l'avons déjà vu, il faut apporter quelques modifications mineures à la base de données de chez Jean-Pierre que nous avons présenté dans une de nos leçons se trouvant à cette adresse, en cliquant ici.

Les instructions SQL permettant de créer la base de données book_sc_livre sont présentées dans le Listing 1.

Listing 1. : book_sc_livre.sql - Le programme permettant de créer la base de données book_sc_livre.

Bien que l'interface d'origine de chez Jean-Pierre soit tout à fait correcte, nous devons la modifier légèrement pour pouvoir la mettre en ligne.

Voici la liste des modifications que nous avons apportées à la base de données d'origine :

L'ajout d'autres champs d'adresses pour les clients. Ces champs sont particulièrement importants, maintenant que nous implémentons une application plus réaliste.

L'ajout d'une adresse de livraison dans les commandes. L'adresse d'un client peut être différente de l'adresse de livraison, en particulier s'il se sert de notre site pour offrir un cadeau.

L'ajout d'un champ pour les commandes que les clients ont passés et qu'ils peuvent nous envoyer par Mail, via notre site, afin que nous puissions noter les commandes qu'ils ont commandés et qu'elles sont ensuite, enregistrées dans notre base de données pour avoir une trace.

L'ajout d'un tableau pour les catégories et d'une colonne catid dans le tableau books. Si nous trions les livres par catégories, le site sera plus simple à utiliser.

L'ajout de amount dans le tableau orders, pour pouvoir modifier le prix des articles. Il faut en effet connaître le prix d'un article au moment où le client l'a acheté.

L'ajout d'un tableau admin pour enregistrer le login et le mot de passe des administrateurs.

La suppression du tableau les_commentaires_livres. Au lieu d'ajouter un résumé pour chaque livre, nous préférons ajouter un champ de description dans le tableau books.

Pour configurer cette base de données sur votre système, il suffit d'exécuter le script book_sc_livre.sql sous le nom de l'utilisateur root de MySQL.

Vous devrez naturellement saisir le mot de passe root selon votre serveur local.

Il faudra au préalable modifier le mot de passe de l'utilisateur book_sc_livre, pour en choisir un plus adapté que "password".

Nous avons également fourni un fichier d'exemple contenant plusieurs données. Ce fichier s'intitule populate.sql. Vous pouvez ajouter ces données dans la base de données, en exécutant ce fichier avec MySQL, comme précédemment.

Implémentation du catalogue en ligne :

Dans cette application, le catalogue est implémenté à l'aide de trois scripts : la page principale, la page des catégories et la page de livres.

La page d'accueil du site est générée par un script appelé index.php. La sortie de ce script est présentée à la figure 3.

Vous remarquerez que, en plus de la liste des catégories, il y a un lien vers le caddie dans le coin supérieur droit de l'écran, ainsi que quelques informations résumant le contenu de ce caddie. Ces informations apparaissent sur toutes les pages du site.

Si un utilisateur clique sur l'une des catégories, il est amené sur la page de la catégorie correspondante, générée par le script show_cat.php. La page correspondant aux livres qui traitent Logiciels de Calculs Composants Électroniques est présentée à la figure 4.

Tous les livres de cette catégorie sont présentés sous la forme de liens. Si un utilisateur clique sur l'un de ces liens, il obtient les détails du livre correspondant. La figure 5 présente un exemple de page affichant les détails d'un livre.

Sur cette page, en plus du lien Votre Panier, nous avons un lien Ajouter au panier grâce auquel l'utilisateur peut sélectionner un article. Nous y reviendrons lorsque nous nous attaquerons à l'implémentation du caddie.

Intéressons-nous maintenant à chacun de ces trois scripts.

Liste des catégories :

Le premier script, index.php, fournit la liste de toutes les catégories de la base de données. Il est présenté dans le Listing 2.

Listing 2. : index.php - Ce script génère la page d'accueil du site.

Ce script commence par inclure book_sc_fns.php, le fichier qui inclut toutes les bibliothèques de fonctions de cette application.

Après cela, nous devons débuter une session session_start() pour pouvoir utiliser le caddie. Chaque page de ce site se servira de la session.

Viennent ensuite, quelques appels à des fonctions de génération HTML, comme do_html_header() et do_html_footer() (ces deux fonctions sont définies dans output_fns.php).

Il y a ensuite, une partie du code qui s'occupe de vérifier si l'utilisateur s'est loggé en tant qu'administrateur, et qui propose des options de navigation légèrement différentes, si c'est le cas. Nous reviendrons sur cette partie dans la section consacrée aux fonctions d'administration.

La partie la plus importante du script est la suivante :

$cat_array = get_categories() ; // récupère les catégories dans la base de données.

display_categories($cat_array) ; // Affiche les catégories sous la forme de liens.

Les fonctions get_categories() et display_categories() sont définies dans les bibliothèques book_fns.php et output_fns.php, respectivement. La fonction get_categories() renvoie un tableau contenant les catégories du système, qui est ensuite passé à display_categories(). Intéressons-nous maintenant au code de get_categories(). Vous le trouverez dans le Listing 3.

Listing 3. : La fonction get_categories() de output_fns.php. - La fonction qui récupère une liste de catégories dans la base de données.

Comme vous pouvez le constater, cette fonction se connecte à la base de données et récupère la liste de tous les identificateurs de catégories et les noms correspondants. Nous nous servons pour cela d'une fonction appelée db_result_to_array(), qui se trouve dans db_fns.php. Cette fonction est présentée dans le Listing 4. Elle prend en argument un identificateur de résultat MySQL, et renvoie un tableau de lignes indexées numériquement, dans lequel chaque ligne est en fait un tableau associatif.

Listing 4. : La fonction db_result_to_array() de db_fns.php - La fonction qui convertit un identificateur de résultat MySQL, en un tableau de résultats.

Dans notre cas, nous renvoyons ce tableau à index.php, où nous le passons ensuite à la fonction display_categories() de output_fns.php. Cette fonction affiche chaque catégorie sous la forme de liens vers la page contenant les livres de cette catégorie. Le code de cette fonction est présenté dans le Listing 5.

Listing 5. : La fonction display_categories() de output_fns.php - La fonction qui affiche un tableau de catégories sous la forme d'une liste de liens vers ces catégories.

Cette fonction convertit chaque catégorie de la base de données en un lien. Chaque lien est ensuite passé au script suivant : show_cat.php, mais chaque fois avec un paramètre différent ; l'identificateur de la catégorie (catid). Il s'agit d'un identificateur unique, généré par MySQL, qui peut être utilisé pour identifier une catégorie.

Ce paramètre, qui passe au script suivant, détermine en fin de compte la catégorie qui nous intéresse.

Liste des livres d'une catégorie :

Le processus permettant de lister les livres d'une catégorie est très comparable. Le script qui s'occupe de cette tâche est appelé show_cat.php, et vous trouverez son code dans le Listing 6.

Listing 6. : Ce script show_cat.php affiche les livres d'une catégorie particulière.

La structure de ce script est tout à fait semblable à celle de la page d'accueil, à la différence près que nous cherchons cette fois des livres et non des catégories.

Nous commençons avec session_start(), comme d'habitude, puis nous convertissons l'identificateur de la catégorie que nous avons reçu en un nom de catégorie, grâce à la fonction get_category_name() :

$name = get_category_name($catid) ;

Cette fonction recherche le nom de la catégorie dans la base de données. Vous trouverez son code dans le Listing 7.

Listing 7. : La fonction get_category_name() de book_fns.php - Cette fonction convertit un identificateur de catégorie en un nom de catégorie.

Après avoir récupéré le nom de la catégorie, nous pouvons afficher un en-tête HTML et continuer notre traitement, en affichant la liste des livres de la base de données qui appartiennent à la catégorie spécifiée du Listing 6 :

$book_array = get_books($catid) ;

display_books($book_array) ;

Les fonctions get_books() et display_books() sont semblables aux fonctions get_categories() et display_categories(), c'est pourquoi nous n'allons pas les présenter ici. La seule différence est que nous cherchons des informations dans le tableau books, au lieu de les chercher dans le tableau categories.

La fonction display_books() fournit un lien vers chaque livre de la catégorie, via le script show_book.php. Une fois encore, chaque lien est accompagné d'un paramètre. Cette fois-ci, il s'agit du code ISBN du livre en question.

A la fin du script de show_cat.php du Listing 6, vous verrez qu'une partie du code qui s'occupe d'afficher d'autres fonctions si l'utilisateur est en fait un administrateur. Nous y reviendrons dans la section consacrée aux fonctions d'administration.

Afficher les détails d'un livre :

Le script show_book.php prend en paramètre un code ISBN, et affiche les détails du livre correspondant. Le code de ce script est présenté dans le Listing 8.

Listing 8. : Ce script show_book.php affiche les détails d'un livre particulier.

Une fois encore, le contenu de ce script ressemble beaucoup à celui des deux programmes précédents. Nous commençons par ouvrir une session_start(), puis nous utilisons :

$book = get_book_details($isbn) ;

pour récupérer les informations du livre dans la base de données, puis :

display_book_details($book) ;

pour afficher les données en HTML.

Il convient de noter que la fonction display_book_details() cherche un fichier image pour le livre, sous le nom images/$isbn.jpg. Si ce fichier n'existe pas, aucune image n'est affichée.

Le reste de ce script s'occupe de configurer la navigation. Un utilisateur normal doit voir les options Continuer vos achats et Ajouter au panier, pour revenir sur la page des catégories, et ajouter un livre dans son caddie, respectivement. Si un utilisateur s'est loggé en tant qu'administrateur, il doit obtenir d'autres options, que nous étudierons dans la section consacrée à l'administration.

Cela termine notre étude des fonctionnalités de base du système de catalogue. Nous allons maintenant nous intéresser au code des fonctionnalités du caddie dans le troisième chapitre.

Nous terminons ainsi ce deuxième chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation du Caddie, etc. ...


Implémentation du Caddie

Implémentation d'un Caddie (3ème partie) :

Implémentation du Caddie :

La fonctionnalité du caddie fait intervenir une variable de session appelée $cart. Il s'agit d'un tableau associatif contenant des codes ISBN comme clés, et des quantités comme valeurs. Par exemple, si j'ajoute un exemplaire de ce livre dans mon caddie, celui-ci contiendra :

920003 => 1

C'est-à-dire un exemplaire du livre dont le code ISBN est 920003. Lorsque l'utilisateur ajoute des livres dans son caddie, ceux-ci sont ajoutés dans le tableau. Lorsque nous affichons le contenu du caddie, nous nous servons du tableau $cart pour afficher les détails des livres à l'aide de la base de données.

Nous nous servons également de deux autres variables de session pour contrôler l'affichage de l'en-tête dans les colonnes Total Article et Total Prix. Ces variables sont appelées respectivement $items et $total_price.

Utiliser le script show_cart.php :

Intéressons-nous maintenant à l'implémentation du caddie, en examinant le script show_cart.php. Il s'agit du script qui affiche la page sur laquelle nous arrivons si nous cliquons sur les liens Votre Panier ou Ajouter au panier. Si nous appelons show_cart.php sans aucun paramètre, nous obtenons le contenu de notre caddie. Si nous l'appelons avec un code ISBN en paramètre, le livre correspondant à ce code est ajouté au caddie.

Pour mieux comprendre ce script, examinons la figure 6.

Dans ce cas, nous avons cliqué sur le lien Votre Panier lorsque notre caddie était vide, c'est-à-dire que nous n'avions sélectionné aucun article à acheter.

La figure 7 représente notre caddie après avoir choisi trois livres. Dans ce cas, nous sommes arrivés sur cette page, en cliquant sur le lien Ajouter au panier de la page show_book.php correspondant à ce livre, Électroniques Théoriques Fondamentales - Tome I. Si vous examinez avec attention la barre contenant l'URL, vous constaterez que, cette fois-ci, le script a été appelé avec un paramètre. Ce paramètre est appelé new, et il possède la valeur 920003, qui correspond au code ISBN du livre que nous venons d'ajouter dans le caddie.

A partir de cette page, vous pouvez constater que nous avons deux autres options. Nous pouvons nous servir du bouton Sauvegarder les modifications pour modifier la quantité d'un article dans le caddie. Pour cela, il suffit de modifier directement la quantité et de cliquer sur le bouton Sauvegarder les modifications. Il s'agit en fait un bouton d'envoi qui nous ramène au script show_cart.php, pour mettre à jour le caddie.

De plus, l'utilisateur peut cliquer sur le bouton Aller à la caisse lorsqu'il a terminé ses achats. Nous y reviendrons dans un instant.

Pour l'instant, voici le code du script show_cart.php du Listing 9.

Listing 9. : show_cart.php - Ce script contrôle le caddie.

Ce script peut être décomposé en trois parties principales : l'affichage du caddie, l'ajout d'articles dans le caddie, et l'enregistrement des modifications apportées au caddie. Nous allons les étudier dans les trois prochaines sections.

Afficher le caddie :

Quelle que soit la page d'où nous venons, nous pouvons afficher le contenu du caddie. Dans la configuration de base, lorsqu'un utilisateur vient de cliquer sur Votre Panier, voici la seule partie du code qui sera exécutée.

// Afficher le panier.

if (isset($_SESSION['cart']) && (array_count_values($_SESSION['cart']))) {

display_cart($_SESSION['cart']) ;

}else {

echo "<BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;Il n'y a aucun objet dans votre panier.<BR /><BR /> <HR COLOR = '#888888' />" ;

}

Comme vous pouvez le constater, si le caddie contient des articles, nous appelons la fonction display_cart(). En revanche, si le caddie est vide, nous pouvons afficher un message personnalisé.

La fonction display_cart() se contente d'afficher le contenu du caddie, en format HTML, comme vous pouvez le voir dans les Listings 6 et 7 à cette adresse, en cliquant ici. Le code de cette fonction se trouve dans output_fns.php, et vous pouvez le retrouver dans le Listing 10. Bien qu'il s'agisse d'une fonction d'affichage, elle est suffisamment complexe pour mériter de figurer ici.

Listing 10. : La fonction display_cart.php de output_fns.php - Cette fonction formate et affiche le contenu du caddie.

Voici l'architecture de cette fonction :

  1. Parcourir tous les articles du caddie, et passer le code ISBN de chaque article à la fonction get_book_details(), pour pouvoir résumer les détails de chaque livre.

  2. Afficher l'image de chaque livre, si elle existe. Nous nous servons des étiquettes d'image HTML, height et width pour réduire un peu la taille de l'image. Cela signifie que les images seront un peu déformées, mais elles sont suffisamment petites pour que cela ne pose pas de problème. Si cela vous gêne, vous pouvez toujours modifier leur taille avec la bibliothèque gd que nous avons présentée dans une de nos leçons PHP, ou générer manuellement des images plus petites pour chaque produit.

  3. Transformer chaque entrée du caddie en un lien vers le livre correspondant, c'est-à-dire vers show_book.php avec le code ISBN comme paramètre.

  4. Si nous appelons la fonction et si le paramètre $change vaut true (ou s'il n'est pas défini, puisqu'il vaut true par défaut), nous affichons les cases contenant les quantités d'articles dans un formulaire se terminant par le bouton Sauvegarder les modifications. Lorsque nous nous servirons à nouveau de cette fonction après être sorti du magasin, l'utilisateur ne devra pas pouvoir modifier sa commande.

Cette fonction n'est pas très complexe, mais elle s'occupe de plusieurs points importants, c'est pourquoi il peut être très intéressant de la lire avec attention.

Ajouter des articles dans le caddie :

Si un utilisateur vient de la page show_cart.php, en ayant cliqué sur le bouton Ajouter au panier, il faut s'occuper de sa dernière commande avant d'afficher le contenu de son caddie.

Tout d'abord, si l'utilisateur n'avait pas encore ajouté d'article dans son caddie, nous devons créer un nouveau caddie :

// Si le panier est vide, créer un nouveau caddie

if (!isset($_SESSION['cart']))

{

$_SESSION['cart'] = array() ;

$_SESSION['items'] = 0 ;

$_SESSION['total_price'] = 0.00 ;

}

Pour commencer, le caddie est vide.

Ensuite, après avoir configuré le caddie, nous pouvons y ajouter l'article :

// Nombre de livres

if (isset($_SESSION['cart'][$new]))

{

$_SESSION['cart'][$new] ++ ;

}else {

$_SESSION['cart'][$new] = 1 ;

}

Dans cette partie du code, nous vérifions si l'article a déjà été ajouté dans le caddie. Si c'est le cas, nous incrémentons la quantité de cet article. Dans le cas contraire, nous ajoutons le nouvel article dans le caddie.

Ensuite, nous devons calculer le montant total de la commande et le nombre total d'articles dans le caddie. Pour cela, nous faisons appel aux fonctions calculate_price() et calculate_items() :

$_SESSION['total_price'] = calculate_price($_SESSION["cart"]) ;

$_SESSION['items'] = calculate_items($_SESSION['cart']) ;

Ces fonctions se trouvent dans la bibliothèque book_fns.php. Leur code est présenté dans les Listings 11 et 12, respectivement.

Listing 11. : La fonction calculate_price() de book_fns.php - Cette fonction calcule et renvoie le montant total de la commande du client.

Comme vous pouvez le constater, la fonction calculate_price() va chercher le prix de chaque article du caddie dans la base de données. Cette approche est un peu lente, c'est pourquoi nous enregistrons les prix et le nombre total d'articles dans des variables de session, et que nous ne les recalculons que lorsque le contenu du caddie est modifié.

Listing 12. : La fonction calculate_items() de book_fns.php - Cette fonction calcule et renvoie le nombre total d'articles du caddie.

La fonction calculate_items() est plus simple. Elle se contente de parcourir le caddie et d'ajouter les quantités des différents articles pour obtenir le nombre total d'articles.

Enregistrer le caddie modifié :

Si l'utilisateur a cliqué sur le bouton Sauvegarder les modifications dans le script show_cart.php, le processus est un peu différent. Dans ce cas, nous venons d'un formulaire d'envoi. Si vous examinez le code attentivement, vous verrez que le bouton Sauvegarder les modifications est en fait le bouton d'envoi d'un formulaire. Ce formulaire contient la variable cachée save. Si cette variable est définie, nous savons que nous sommes arrivés sur ce script avec le bouton Sauvegarder les modifications. Cela signifie que l'utilisateur a probablement modifié des quantités dans son caddie, et que nous devons les mettre à jour.

Si vous revenez aux champs de texte dans la partie de ce script consacrée au formulaire Sauvegarder les modifications, vous constaterez que leur nom provient du code ISBN de l'article qu'ils représentent :

echo "<input type=\"text\" name=\"" . $isbn . "\" value=\"" . $qty."\" STYLE = 'background-color: #D3DDE2; color: #000000; font-weight: bold; border-width: 2px; font-size:10pt' size=\"3\">" ;

Intéressons-nous maintenant à la partie du script qui enregistre les modifications :

// Enregistrer les informations

if (isset($_POST['save']))

{

foreach ($_SESSION['cart'] as $isbn => $qty)

{

if ($_POST[$isbn] == 0)

{

unset($_SESSION['cart'][$isbn]) ;

} else {

$_SESSION['cart'][$isbn] = $_POST[$isbn] ;

}

}

$_SESSION['total_price'] = calculate_price($_SESSION['cart']) ;

$_SESSION['items'] = calculate_items($_SESSION['cart']) ;

}

Vous pouvez constater que nous parcourons le caddie, et que pour chaque variable $isbn du caddie, nous vérifions la variable possédant ce nom. Il s'agit des champs provenant du formulaire Sauvegarder les modifications.

Si l'un de ces champs vaut 0, nous supprimons l'article correspondant du caddie à l'aide de la fonction unset(). Sinon, nous mettons à jour le caddie, en fonction des champs du formulaire comme ceci :

if ($_POST[$isbn] == 0)

{

unset($_SESSION['cart'][$isbn]) ;

} else {

$_SESSION['cart'][$isbn] = $_POST[$isbn] ;

}

Après ces mises à jour, nous appelons une fois de plus les fonctions calculate_price() et calculate_items() pour déterminer les valeurs des variables de session $total_price et $items.

Afficher la barre d'en-tête :

Vous avez déjà remarqué que la barre d'en-tête de chaque page contient un résumé du contenu du caddie. En effet, nous affichons la valeur des variables de session $total_price et $items dans cette barre, à l'aide de la fonction do_html_header().

Ces variables sont enregistrées lors de la première visite de l'utilisateur sur la page show_cart.php. Nous devons également gérer le cas où l'utilisateur n'a pas encore visité cette page. Le code correspondant se trouve aussi dans la fonction do_html_header() :

$_SESSION['items'] = 0 ;

$_SESSION['total_price'] = 0.00 ;

Sortir du magasin :

Lorsque l'utilisateur clique sur le bouton Aller à la caisse de son caddie, il active le script checkout.php. A partir de cette page, il commencera activer la connexion qui doit être effectuée via SSL, que l'on verra par la suite de nos leçons lors du paiement, bien qu'il soit nécessaire de se connecter pour une petite application si vous voulez vendre.

La page de sortie est présentée à la figure 8.

Ce script demande au client de saisir son adresse principale (et adresse de livraison si elle est différente). Il s'agit d'un script très simple, que vous retrouverez dans le Listing 13.

Listing 13. : Le script checkout.php demande au client de saisir diverses informations.

Ce script ne contient aucune surprise particulière. Si le caddie est vide, le script avertit le client et le formulaire ne peut être affiché. Dans le cas contraire, il affiche le formulaire de la figure 8.

Si l'utilisateur clique sur le bouton Achat en bas du formulaire. Il arrive sur le script purchase.php. La figure 9 représente la sortie de ce script.

Le code de ce script est légèrement plus compliqué que celui de checkout.php. Vous le trouverez dans le Listing 14.

Listing 14. : Le script purchase.php - Ce script enregistre les détails de la commande dans la base de données et récupère les détails de paiement.

Sa structure est assez simple : nous vérifions si l'utilisateur à correctement rempli le formulaire, et nous ajoutons ses informations dans la base de données sauf les informations de la carte bancaire pour des raisons de sécurité, en appelant la fonction insert_order(). Il s'agit d'une petite fonction qui se contente d'ajouter les détails du client dans la base de données (uniquement le formulaire de la figure 8). Son code se trouve dans le Listing 15.

Listing 15. : La fonction insert_order() de order_fns.php - Cette fonction ajoute tous les détails de la commande du client dans la base de données.

Cette fonction est assez longue, parce que nous devons insérer les détails du client, les détails de la commande et les détails de chaque livre commandé.

A noter : Dans le fichier order_fns.php. Vous devez changer les paramètres de la fonction mail() par votre Mail y compris l'URL de votre site. Quant au paiement, on verra par la suite sur une de nos leçons suivantes (4ème partie), et on aura l'occasion de vous expliquer lors de l'implémentation du paiement. Par ailleurs, nous avons mis des commentaires dans le fichier order_fns.php pour en faciliter votre tâche.

Nous déterminons ensuite les frais d'envoi, en fonction de l'adresse du client, et nous les affichons avec les lignes suivantes (voir le fichier book_fns.php) :

function calculate_shipping_cost()

{

return 1.50 ;

}

La fonction calculate_shipping_cost() renvoie toujours la même somme,1.50 €. Pour un site réel, vous devez choisir un moyen d'expédition, vous devez déterminer combien il vous coûtera pour les différentes destinations, et calculer les frais d'envoi en conséquence.

Nous affichons ensuite un formulaire (figure 9) permettant au client de saisir les informations de sa carte de crédit, grâce à la fonction display_card_form() de la bibliothèque de output_fns.php.

Nous terminons ainsi ce troisième chapitre de cette leçon, et nous verrons dans le prochain, L'implémentation du paiement.


Implémentation du Paiement Caddie

Implémentation d'un Caddie (4ème partie) :

Implémentation du paiement :

Lorsqu'un utilisateur clique sur le bouton Achat, nous nous occupons de la transaction avec le script process.php et celui de order_fns.php. La figure 10 représente le résultat d'un récapitulatif d'un paiement de votre commande puis, en cliquant une seconde fois sur le bouton Achat, le paiement est effectué et, nous avions choisi PayPal. Bien sûr, il y a d'autres Sociétés bancaires qu'on vous laisse le soin de choisir.

Dans tous les cas, il faut systématiquement ouvrir un compte bancaire que l'on verra dans un instant.

Le code de process.php se trouve dans le Listing 16.

Listing 16. : Ce script process.php s'occupe de la transaction du client et affiche son résultat.

L'essentiel de ce script se trouve dans les lignes suivantes :

if (process_card($_POST))

{

// Caddie vide.

session_destroy() ;

echo "<BR/><BR/>&nbsp;&nbsp;&nbsp;&nbsp;Nous vous remercions d'avoir acheté nos ouvrages électroniques et informatique. Votre commande a été enregistré et vous recevrez par votre E-Mail.<BR /><BR />" ;

display_button("index.php", "continue-shopping", "Continue Shopping") ;

}

Comme dans les autres fonctions qui font directement référence à $_POST, dans certains cas, on peut toujours activer track_vars. Nous nous occupons ensuite de la transaction, et si tout se passe bien, nous fermons sa session.

La fonction qui s'occupe du traitement de la carte de crédit se contente de renvoyer true.

Pour un site réel, vous devez choisir un mécanisme de validation de la transaction. Grâce à la fonction ci-après de process_card() du fichier order_fns.php. Vos clients peuvent faire une ou plusieurs transactions que si vous eûtes un id marchant (identification du marchant) auprès de PayPal par exemple, afin que vous puissiez vendre vos articles et, nous vous indiquons ces paramètres :

Listing 16 - 1. : Cette fonction process_card() de order_fns.php - S'occupe de la transaction du client vers PayPal.

A noter : La fonction display_button() du fichier order_fns.php ci-dessous, vous ne devez pas mettre d'espaces entre les mots, tout doit être serré afin que cette dernière puisse fonctionner correctement. Ensuite, vous devez mettre également vos paramètres personnels tels que E-Mail et votre URL de votre site mentionné en couleur rouge sans espaces.

display_button("https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=Mettez_Ici_Votre_E-Mail_Sans_Espaces&item_name=$Quantite&amount=$Totaux&no_shipping=0
&no_note=1&currency_code=EUR&lc=FR&return=Mettez_Ici_Votre_URL_de_Votre_Site_Sans_Espaces
&bn=PP-BuyNowBF", "purchase", "Purchase") ;

Vous pouvez notamment faire appel à un service de validation de transactions. Il existe dans ce cas plusieurs possibilités, en fonction de l'endroit où vous vous trouvez. Certains de ces services sont effectués en temps réel, contrairement à d'autres. Vous pouvez faire votre choix en fonction du service que vous proposez. S'il s'agit d'un service en ligne, il peut être intéressant de valider la transaction en temps réel. Si vous vendez des articles matériels, c'est un peu moins important. De toute manière, ces fournisseurs de services vous épargnent de prendre la responsabilité d'enregistrer les numéros de carte de crédit.

Enregistrer les numéros de carte de crédit dans votre base de données. Nous ne vous recommandons pas cette approche en cas de fraude quelconque.

Ces considérations terminent notre étude du module de paiement et du caddie.

Implémentation d'une interface d'administration :

L'interface d'administration que nous avons implémentée est très simple. Nous avons seulement mis en place une interface Web pour la base de données, complétée par un mécanisme d'authentification. Nous nous sommes principalement servi du code que nous avions mis en œuvre dans une de nos leçons au chapitre 13. Nous l'avons recopié dans ce chapitre, pour compléter notre étude, mais sans nous attarder dessus.

L'interface d'administration demande aux utilisateurs de se logger avec le fichier login.php, qui les renvoie ensuite au menu d'administration, admin.php. La page de login est présentée à la figure 11. Nous vous rappelons son code tout simplement.

Son code est très simple :

Listing 17 : Ce script de login.php pour accéder au menu d'administration.

Le code du menu d'administration est présenté dans le Listing 17. 1.

Listing 17. 1. : Ce script de admin.php authentifie l'administrateur et lui permet d'accéder aux fonctions d'administration.

Le menu d'administration est présenté à la figure 12.

Ce code vous est probablement familier. Il ressemble, en effet à un script du chapitre 13 concernant les signets ou les Bookmarks. Lorsque l'administrateur arrive sur ce script, il peut modifier son mot de passe ou fermer sa session. Ce code est presque identique à celui du chapitre 13, c'est pourquoi nous allons pas l'étudier plus en détail ici.

Après l'ouverture de la session, nous identifions l'administrateur à l'aide de la variable de session $username = $_SESSION["admin_user"] = $passwd et de la fonction check_admin_user(). Cette fonction, ainsi que toutes les autres fonctions utilisées par les scripts d'administration, se trouve dans la bibliothèque de fonctions admin_fns.php.

Si l'administrateur choisit d'ajouter une nouvelle catégorie ou un nouveau livre, il arrive sur insert_category_form.php ou insert_book_form.php, en fonction de son choix. Ces scripts affichent un formulaire, que l'administrateur doit remplir. Ces formulaires sont ensuite traités par un script particulier (insert_category.php ou insert_book.php), qui vérifie que le formulaire est rempli correctement, et qui insère les nouvelles données dans la base de données. Nous nous contenterons d'étudier dans cette leçon l'insertion de nouveaux livres, puisque l'insertion d'une nouvelle catégorie est très similaire.

La sortie de insert_book_form.php est présentée à la figure 13.

Vous remarquerez que le champ Catégorie des livres est un élément HTML SELECT. Les options de cet élément SELECT proviennent d'un appel à la fonction get_categories(), que nous avons déjà vue.

Lorsque l'administrateur clique sur le bouton Additionner le livre, le script insert_book.php est activé. Le code de ce script est présenté dans le Listing 18.

Listing 18. : Ce script de insert_book.php valide les données d'un nouveau livre et les ajoute dans la base de données.

Vous pouvez constater que ce script appelle la fonction insert_book(). Cette fonction, ainsi que toutes les autres fonctions intervenant dans les scripts d'administration, se trouve dans la bibliothèque de fonctions admin_fns.php.

En plus d'ajouter de nouvelles catégories et de nouveaux livres, l'administrateur peut modifier et supprimer ces éléments. Nous avons implémenté cette caractéristique, en réutilisant le code existant au maximum. Lorsque l'administrateur clique sur le lien Aller sur le site principal dans le menu d'administration, il se retrouve sur la page contenant la liste des catégories, index.php, et peut naviguer sur le site de la même manière qu'un utilisateur classique, en utilisant les mêmes scripts.

Cependant, la navigation des administrateurs est un peu différente. Les options proposées aux administrateurs ne sont pas les mêmes que celles des utilisateurs classiques, puisqu'ils ont enregistré la variable de session $username = $_SESSION["admin_user"] = $passwd. Par exemple, si nous reprenons la page show_book.php que nous avons déjà vue dans cette leçon, (voir figure 5 en cliquant ici), vous pouvez constater que le menu d'options est légèrement différent (voir figure 14).

Sur cette page, l'administrateur a accès à de nouvelles options : Modifier les détails du livre et Menu administrateur. Vous remarquerez également qu'aucun caddie n'est affiché dans le coin supérieur droit de la page. Celui-ci est remplacé par un bouton Déconnecté.

Le code de cette fonctionnalité, qui se trouve dans le Listing 8, est le suivant : en cliquant ici.

if (check_admin_user())

{

display_button("edit_book_form.php?isbn=".$isbn."", "edit-item", "Edit Item") ; echo "<BR />" ;

display_button("admin.php", "admin-menu", "Admin Menu") ; echo "<BR />" ;

display_button($target, "continue", "Continue") ; echo "<BR />" ;

}

Si vous reprenez le script show_cat.php, vous constaterez qu'il contient également ces options.

Si l'administrateur clique sur le bouton Modifier les détails du livre, il sera redirigé vers le script edit_book_form.php. La sortie de ce script est présentée à la figure 15.

Il s'agit en fait du même formulaire que celui que nous avions utilisé pour lire les détails d'un livre. Nous avons intégré une option dans ce formulaire pour transmettre et afficher les données d'un livre existant. Nous avons suivi la même démarche avec le formulaire des catégories de livres. Pour mieux comprendre tout cela, intéressons-nous au Listing 19.

Listing 19. : La fonction display_book_form() de admin_fns.php - Ce formulaire sert à la fois de formulaire d'insertion et de formulaire de modification.

Si nous passons en paramètre un tableau contenant les données d'un livre, ce formulaire passe en mode d'édition et remplit les champs avec les données existantes :

<input type = "text" name = "price" value = "<?php echo $edit? $book['price'] : ''; ?>"

Nous obtenons même un autre bouton d'envoi. En fait, il en existe deux pour le formulaire d'édition (un pour mettre à jour le livre, et un autre pour le supprimer). Ces boutons appellent respectivement les scripts edit_book.php et delete_book.php, qui mettent à jour la base de données en conséquence.

L'équivalent de ces scripts pour la gestion des catégories de livres fonctionne de la même manière, à un détail près. Lorsqu'un administrateur tente de supprimer une catégorie, celle-ci n'est pas supprimée si elle contient encore des livres. Nous le vérifions avec une requête dans la base de données. Cela nous permet d'éviter certains problèmes que nous aurions en cas de suppression intempestive. Nous avons déjà abordé ces problèmes dans une de nos leçons (voir chapitre 7), en cliquant ici. Dans notre cas, si une catégorie contenant des livres est supprimée, ces livres deviennent orphelins. Il est donc impossible de savoir dans quelle catégorie ils se trouvent, il est impossible de les retrouver, en passant par l'interface du site !

Cela termine notre étude de l'interface d'administration.

A Noter : Nous avons implémenté un système de caddie relativement simple. il existe plusieurs améliorations que nous pourrions y apporter :

Pour un magasin en ligne réel, il serait intéressant d'implémenter un système de suivi de commande. Pour l'instant, on vous laisse le soin d'apporter une amélioration concernant le caddie ! C'est comme ça qu'on arrive dans la vie sur la programmation en PHP ! Nous avons fait beaucoup d'efforts de notre côté !

Les clients doivent pouvoir suivre la progression de leurs commandes sans vous contacter. Nous pensons qu'il est important qu'un client n'est pas besoin de se logger pour consulter le catalogue en ligne. Cependant, le simple fait d'authentifier les clients leur permet de consulter leurs commandes antérieures, et vous permet d'effectuer des statistiques pour essayer d'établir des profils de clients.

Pour l'instant, les images des livres doivent être transmises dans le dossier d'images par FTP, et il faut leur donner un nom correct. Il serait intéressant de pouvoir charger ces fichiers dans la page d'insertion des nouveaux livres.

Vous pouvez implémenter un système de login pour les utilisateurs, personnaliser le site en fonction des clients, et recommander des livres, ou encore proposer des résumés en ligne, des programmes de fidélisation, des systèmes de vérification des stocks, etc. ...

Cependant, nous avons regroupé tous les fichiers au format ZIP, (il suffit de les décompresser) afin que vous puissiez les télécharger avec ou sans carte bancaire concernant le caddie.

Avec Carte Bancaire, en cliquant ici. [Exemple 1].

Sans Carte Bancaire, en cliquant ici. [Exemple 1 - bis].

Pour visualiser l'aperçu, en cliquant ici. [Exemple 1 - ter].

Nous terminons ainsi cette quinzième leçon et nous verrons dans la prochaine d'autres programmes ...